Page MenuHomePhabricator

EO: Ecore API
Open, NormalPublic


This is a part of T5301 (major interface rework for EO).

Ecore mainloop needs to be a proper efl object so multiple loops can exist in multiple threads and can interact with each-other, message/call back and forth etc.

  • Efl.Loop needs to exist
  • EFl.Loop neds to not rely on globals so multiple instances can be created
  • Cleanup ecore poller for EO (no cb function): T5524
  • Cleanup ecore_types.eot
  • Fd handlers (Efl.Loop.Handler)
  • Ecore Event stream (Efl.Loop.Message + Efl.Loop.Message.Handler)
  • Rename ecore_main_loop_get() to efl namespace
  • Efl.Loop events for signals
    • HUP
    • USR (1 & 2)
  • Efl.Task common interface for running executeables and new threads

    Executables and Threads should be similar so it is easy to move work from executables to threads and back depending on what would be best. Having at least one form of consistent I/O that works between threads and processes (like stdin/out or specialized pipe fd's). Also pause/unpause as well as priority/scheduling controls.
  • Ecore Exe -> Efl.Exe (use Efl.Task)

    Need an Eo API for launching Exe's and controlling them and knowing when they exit etc. (what Ecore_Exe stuff did).
  • Ecore thread creation/destruction plus per thread loop creation + execution (Efl.Task used)

    The idea is one Efl.Loop per thread, with a local Eo object representing the spawned thread on the other end so you can use this object and methods on it to listen to events from the other loop, send things to it or even control it.
  • Efl/Eo/Efl.Task version of ecore_main_loop_thread_safe_call_sync/async();
    • Probably a method on the Efl.Task iface to call a func ptr + void ptr + sync & async versions
  • Per-loop/executable process I/O to/from parent process or parent "loop" (interface for this)
    • Efl.Something interface for handling writes/sends and events for returning data coming back
    • Inherit this interface in Efl.Task and Efl.Loop
    • For exe's a flag to re-use stdio or special fd's
    • Probably have option for line based parsing due to common usage for stdio
    • Threads can have special I/O channel for void ptrs + free funcs and/or shared objects
  • Clean up signal to event conversion code
    • Dedicate a thread that blocks all signals, uses sigwaitinfo() + pipe back to main loop
  • Efl.Loop events for power, battery and other lifecycle events (pause, resume, etc.)
    • System Time/date change
    • Hostname change
    • Locale/region change
    • Low memory
    • Charging status change
    • Low battery
    • On battery power (or not i.e. AC)

I/O from main loop to parent process by default would be stdio/stream based using stdio, unless launched with specific environment vars then special fd's would be inherited from a fork other than stdio and go to parent process as a side-channel available to efl apps. Needs loop methods to write such data and events to deliver input. Also Efl.Task for the other side too. The same I/O methods would come from the Efl.Task interface and be usable between threads (parent/child thread - this isn't strictly correct but an idea we need to introduce). Try and make threads and exe's as consistent as possible this way. Efl.Task would define environment vars, commandline and/or argument array, same events for exit of thread/process and consistent exit code mechanism. Threads can have also the ability to send void ptrs or shareable objects around.

Efl.Net style Elf.Io.* reader/writer etc. interfaces seem far too complex for something that should be a lot simpler.

jpeg created this task.May 23 2017, 11:21 PM
jpeg updated the task description. (Show Details)
jpeg updated the task description. (Show Details)May 28 2017, 10:02 PM
cedric raised the priority of this task from TODO to High.Jul 10 2017, 2:19 PM
jpeg reassigned this task from jpeg to raster.Nov 13 2017, 2:27 AM
jpeg renamed this task from Ecore EO API to EO: Ecore API.Nov 13 2017, 2:38 AM
jpeg updated the task description. (Show Details)
cedric updated the task description. (Show Details)Nov 14 2017, 10:55 AM

I think we are ok with no fd handler at this point in the .eo has this are unlikely to work for most bindings anyway. They can stay legacy for the time being.

To close this task, we should just cleanup the .eo with the left over future.

I'm actually already doing the work to add handlers (fd and win32 handle "fd handlers"). I need this to properly make efl loop objects and move all the loop data into the object so we can have multiple loops (per thread for example). so it's kind of essential to do this. At least to make this ever possible.

raster updated the task description. (Show Details)Dec 21 2017, 7:07 AM
raster updated the task description. (Show Details)Jan 1 2018, 3:24 AM
raster updated the task description. (Show Details)Jan 1 2018, 3:38 AM
raster updated the task description. (Show Details)Jan 1 2018, 10:35 PM
raster updated the task description. (Show Details)Jan 1 2018, 10:46 PM
raster updated the task description. (Show Details)Jan 1 2018, 11:02 PM
raster updated the task description. (Show Details)Jan 1 2018, 11:11 PM
raster updated the task description. (Show Details)Jan 2 2018, 8:18 PM
raster updated the task description. (Show Details)Jan 4 2018, 9:51 PM
raster updated the task description. (Show Details)Jan 4 2018, 10:03 PM
raster updated the task description. (Show Details)

my takes on this:

  • Efl.Task can implement Efl.Io.Reader and Efl.Io.Writer as generic ways to pass blobs around. For processes, just map to fds and use Efl.Io.Reader.Fd and Efl.Io.Writer.Fd. For threads, you can just send the blobs in memory, notify the receiver thread with Efl.Io.Reader:can_read... once reads happen, consume from the in-memory blob slices, once slice is fully consumed, discard/free it and remove from queue... this is useful for progressive work, related to "thread feedback". Alternatively, Threads can create 2 pipes and also use Efl.Io.Reader.Fd and Efl.Io.Writer.Fd... it's almost zero-work to implement, although bit heavier as there's copy to/from kernel.... Also, providing an Efl.Io.Pipe that isolates this behavior would be generally useful.
  • Efl.Task should offer a future to notify once all work is done. Similar to done event of Efl.Io.Copier... if we had a way to create future-for-single-shot-events, as I proposed, it would benefit the whole EFL and this method could be written on top of that... and a similar done() method that retuns a future should exist for Efl.Io.Copier...

As for NO, PLEASE NO section:

  • Efl.Loop events for signals: no, please do not add such events in the loop! They don't belong there, rather in the Efl.Task subclass that deals with processes (fork or exec);
  • Efl.Loop events for power, battery and other lifecycle events (pause, resume, etc.): as above, PLEASE DO NOT! This was a huge mistake introduced in old Ecore since there was no proper events-per-object... Instead there should be some objects that, once instantiated, would listen for such events in the system (dbus, signals, /proc...) and report. They have nothing, ZERO, to do with the main loop... That is, we should have some classes equivalent to UPower and systemd's timedated behavior... once created, these classes would notify of events (if there are subscribed callbacks!), they could also allow further functionality, as set the date, control the power settings... of course there should be a dummy-backend that works elsewhere.
raster updated the task description. (Show Details)Jan 6 2018, 1:47 AM
raster added a comment.EditedJan 6 2018, 2:49 AM

I don't think signal events matter if they are on a task or a loop. They are whole-process events basically do they belong IMHO on the main loop. we can artificially create objects you have to get that then have these specific event cb's on them but IMHO that's just artificial. it just adds an extra step to use them and more code and bloat (constructors, eo files, more code and infra) to have such extra objects.

I'll look into the classes. i did look but the usage seems overly complex as i mentioned. I do want something nicer though to pass things like void *'s (along with free funcs) and objects (shared objects can be passed around from thread to thread safely. that is what they were intended for).

Here is a rough draft so far with no io:

interface Efl.Task ()
   [[ ]]
   methods {
      @property command {
         [[ A commandline that encodes arguments in a command string ]]
         get { }
         set { }
         values {
            command: string; [[ ]]
      @property args {
         [[ Either arguments passed in or arguments that are to be passed ]]
         get { }
         set { }
         values {
            args: array<string>; [[ ]]
      @property env {
         [[ The environment to be passed in or that was passed to the task ]]
         get { }
         set { }
         values {
            env: hash<string, string>; [[ ]]
      run {
         return; future<int>; [[ A future that completes when the task exits ]]
   events {
enum Efl.Exe.Signal {
   [[ ]]

class Efl.Exe (Efl.Object, Efl.Task)
   [[ ]]
   methods {
      signal {
         params {
            signal: Efl.Exe.Signal; [[ Send this signal to the task ]]

as said in IRC, I disagree but as I'm not doing any work on this... I'm shut up and stop bugging about this, IMO, messy design.

barbieri removed a subscriber: barbieri.Jan 6 2018, 6:18 AM

as on irc - i just don't think 3 events justify a whole new object just to hold them when that object will ALWAYS be there for the main loop. you have 2 objects instead of 1. always there. cleaner might be to subclass the mainloop as a special class and have these events on that subclass only. but again... i don't think it's worth the work - at least not atm. not until there is a lot more reason to justify this.

cedric lowered the priority of this task from High to Normal.Jan 11 2018, 3:34 PM
raster updated the task description. (Show Details)Jan 17 2018, 4:31 AM
zmike edited projects, added Restricted Project; removed efl.Jun 11 2018, 6:57 AM
segfaultxavi edited projects, added efl: main loop; removed Restricted Project.Jun 11 2018, 9:01 AM