On Wed, 28 Feb 2018 17:09:18 -0500 Cedric Bail <[email protected]> said:
> -------- Original Message -------- > On February 27, 2018 9:18 PM, Carsten Haitzler <[email protected]> wrote: > > >On Tue, 27 Feb 2018 13:12:59 -0500 Cedric Bail [email protected] said: > > > > wo.. a cedric! long time... > > > >>For whatever reason, I didn't receive the first email of this chain, so will > >> answer here. > >>-------- Original Message -------- > >> On February 27, 2018 7:21 AM, Mike Blumenkrantz > >>[email protected] wrote: > >>>You've certainly raised some valid points which bear further looking into, > >>> thanks! > >>>At a minimum, this patch was intended to introduce a base implementation of > >>> a singleton "app" object which could (and should) have tests written for > >>> it as it's improved upon. If you or others want to do that work feel free, > >>> I've moved on to other items for the near future. > >>>On Tue, Feb 27, 2018 at 12:07 AM Carsten Haitzler [email protected] > >>> wrote: > >>>>On Mon, 26 Feb 2018 11:03:03 -0800 Mike Blumenkrantz > >>>>[email protected] said: > >>>> this change has a fair few problems to it... i don't think this is the > >>>> right > >>>> way to go. > >>>> this change from efl_main_loop_get() doesn't make sense > >>>> - job = efl_add(EFL_IO_MANAGER_CLASS, efl_main_loop_get()); > >>>> > >>>> - job = efl_add(EFL_IO_MANAGER_CLASS, > >>>> efl_app_main_loop_get(efl_app_get())); > >>>> > >>>> > >>>I disagree on both of those line. You get the main loop when your > >>>application > >> start and all your object do get you there. The scenario in which you need > >> to directly access the main loop should be really limited (tests and > >> legacy code are what come to my mind). > >> > > i literally have test code that does: > > > > if (loop == efl_main_loop_get()) { } else { } > > Where is that code ? In efl, it can make sense in some case, but application it's in my test code locally. it's how a callback knows if it's a main loop or some other thread. i re-used the same cb for both and have it do slightly different things. my point here is that if you need access to the app object to get the main loop object... a non- main loop thread cant access the app object unless it's shared... and then we get into the shared mixed with non-shared. :) > should not rely on that as this facility is not available to bindings. It > would prove that we have a design issue and that you can't write the same > application in C as in Python due to our objects limitation. there is a class function that does the same. return efl_app_loop_main_get(EFL_APP_CLASS); for example. that's bindable. just there is a wrapper on top to cut the typing in c/c++ and thats what i used above. the above is btw the sample in my tree. in the efl app parent it's efl_app_main_loop_get(()) ... and that still relies on the C wrapper efl_app_get()... > > i can't do that anymore from threads. the loop does not have an EO parent > > set to the efl app object, so i cant get the parent of my loop and do an > > isa on it... that's why i say... this doesn't make sense... it also doesn't > > make sense to just make it longer. > > This is confusing. Basically you want to be able to do pointer comparison of > something that is not valid (in the thread domain sense) in the thread actually it is due to the domain id of main being different to threads and domain id is in the eoid. thus they will always have a difference. between 2 threads you can't tell the difference though. > context you are in, in C. This point exactly to my remark above. Language > that do not have pointer, like almost every single one binding, won't be able > to do this kind of code. So the logic above is a problem that need solving. I > haven't seen that kind of code before in our code base and can't find it. So > I am at a loss of understanding what you are trying to do here. and that is why having different classes is the right thing efl_isa() can tell me if i'm main or some other thread instantly with a superclass mechanism. :) i don't need access to any object but the loop object i was passed when the thread started (the main loop is sent an arguments event, so are other thread you create - so it's passed in here and the arguments callback handles setup just like main loop). you haven't seen this code before btw... because we haven';t had thread be symmetrical to the main loop. ecore_thread has been special and you know you're in a thread vs main loop.. and there could be only 1 main loop. > >>>>you can't access the app object from anywhere other than the main loop > >>>> thread because it's a thread local object (the default)... so all this > >>>> does it make this longer for no benefit. > >>>> > >>>This is the point. Why would you need to access this object from another > >> thread ? > >> > > you can't know if your loop is the main loop or not with this scheme. if you > > use superclassing then isa() can tell you. if it actually used eo parent > > objects, then getting parent could tell you, with the exception that the > > parent is thread local so this cant work. if it was shared you cross > > domains too. > > Why do you need to know if your loop is the main loop or not ? it alters behaviour. i have a single timeout cb and in main loop it counts up to n timeouts then exits the process, and in both it spawns exe's for testing. > > it's better to superclass here than use parent/child. > > > >>>>if can't be a shared object either because you also do things like: > >>>> - EINA_LIST_FOREACH_SAFE(pd->loops, l, ll, loop) > >>>> > >>>> - efl_del(loop); > >>>>you want to have multiple loops in a single thread-local shared object? > >>>>you > >>>> can't mix shared and non-share objects. > >>>> > >>>There is a lot in this sentence. The fact we can't mix shared and > >>>non-shared > >> object is going to be a serious problem with our parent model and object > >> refcounting in general. Basically we will require to have another tree of > >> shared object on the side that is not connected to the one that are not > >> shared. And all of this object have to be controlled by the user call to > >> the domain API. This is a lot of receipe for error and problems. > >> > > correct. it's just not practical to mix objects that are locked and > > protected with ones that have no locking on them. delete a shared obj and > > it tires to delete non-0shared children. BOOM. the children aren't > > protected with locks etc. ... there are good reasons not to allow the > > "streams to cross". and they have nothing to do with the shared objects > > that provide locking for you, but to do with locked vs not-locked > > objects/data interacting in general > > I think this is another problem to put on the list of problem that the > current domain system bring and another argument to not release that part of > the API. you dont NEED a shared object to make this work. superclassing does it. you can use shared objects and pass them from thread to thread and use them from multiple threads at a time. but they can't reference non-shared objects because of the exact locks vs non locked object discrepancy. this is an issue fundamental to threading and sharing of data and has nothing to do with eo/efl other than it provides a solution to having objects able to be shared across threads safely. it comes with a catch/cost of course as well. > >>>>this wouldn't even be able to delete the other loops belong to threads, > >>>> and multiple loops in a single thread just make zero sense.loops are > >>>> intended to run a thread, not be multiple of them within a thread. i > >>>> thought this had been discussed? > >>>> > >>>It has been and the conclusion was that the new logic that was pushed in > >>>tree > >> broke the previous one which had the intent to make it work. We concluded > >> it was hard to get that working again and not a priority, but not that it > >> should not be a scenario for the future as much as I remember. My > >> expectation with this code is that only the main loop running in the main > >> thread end up there. Overall, this is a details as this new thread model > >> is really not a priority for this release as no bindings can use it and > >> legacy API can still be used. > >> > > i think it's important to set the base here because of exactly the above. i > > remember distinctly discussing face to face in person "1 loop per thread" > > with you. never was there any talk about "let's have multiple loops within > > a thread and somehow have them work together". i see no value in this. it > > just artificially divides up a loop and adds complexity to making them all > > work. > > I am pretty sure I have pointed out to the idea of having "container" loop. > That would enable some more intermediate better sandboxing, but seriously not > a priority. i don't see how you'd want or need a loop for this. any other object can container child objects and have them die along with it including timeouts etc. etc. the same parent loop still runs everything. > > but if that list of loops is for loops across threads, my point stands - it > > can't work for logical , not implementation reasons (unlocked objects being > > nuked from another thread while they may still be running...) > > The intent was as above. If it doesn't work like that, then need to be fixed. > > >><snip> > >>> > >>>>here is what i have been mulling and i think might be right: > >>>> an efl.app or efl.mainloop class that INHERITS from efl.loop. i.e.: > >>>> class Efl.App (Efl.Loop) > >>>> { > >>>> ... > >>>> } > >>>> so the main loop will be of this efl.app or efl.mainloop class and then > >>>> other loops in threads will be of the regular efl.loop class, not the > >>>> efl.app class. no parent + child containing all the loops here and so no > >>>> cross-thread boundaries are crossed. then the efl.app or efl.mainloop > >>>> class can have the signal events move to it. the same main loop or app > >>>> object we had before stays, but it just gets a new class on top. > >>>> > >>>We did consider that too, but we rulled against it as we think it will > >>>likely > >> increase maintenance complexity. We can disagree on that, but overall I > >> don't see why one would be easier than the other. > >> > > i think the exact opposite... :/ > > Sure, then go ahead and change the code. No worry there. No strong opinion on > this case. I am doing that. I think I have a good design and an implementation that's seemingly working ok - enough to show off and then see how people like it. I'll write a design document too. It won't be final, but it'll be enough to get most of the rough nuts and bolts in place. > >>>>it's simpler and won't have the above issues (and others i can begin to > >>>> see/imagining). you know if your loop is the main loop with efl_isa(loop, > >>>> EFL_APP_CLASS) on it. the efl_main_loop_get() can change to efl_app_get() > >>>> and be shorter and sweeter, with perhaps later an efl_current_loop_get() > >>>> that gets the loop for that thread from a TLS that works in threads and > >>>> in main loop too once we have api to spawn threads and handle binding > >>>> them together with comms pipes. > >>>> > >>>I am not a fan at all of relying on TLS for this things especially when all > >> the code will be given a context via at least an object that can lead you > >> back directly to a loop or the application. > >> > > the TLS is a convenience to get your thread's loop without having to find it > > via a parent object. that's all. it's an option. it isn't NEEDED as you get > > passed your loop anyway (well will - via the args event callback that is > > basically your init func for a thread). > > As said above the TLS facility is a short circuit that is not necessarily > available to bindings. If we need that pattern, it means that some bindings > won't be able to do some use case. This is why the general main loop get and > now app_get should remain forever a BETA API that should not be used by > application. I am not sure about that. for c/c++ i think they should be there. given how insanely verbose eo api has now become we're going to end up writing a lot of convenience functions in the end to make it sane. like curl has curleasy... i can smell that already. > >>>>it's simpler than your changes here and has fewer problems. i don't think > >>>> loops will or should be children like you have above of an object. they > >>>> have to be loosely coupled. they need to have just regular structs ptrs > >>>> inside the loop object to track child threads and how to communicate with > >>>> them. to delete them you need to co-operatively request their delete e.g. > >>>> via a pipe/fd setup to the other end, then the loop at the other end > >>>> exits automatically when it gets this event/request on their end of the > >>>> pipe and deletes itself. listen to the del event on the loop object to > >>>> handle shutdown of anything pending on that thread if you want to ensure > >>>> you clean up anything you created on the thread end of things. actually > >>>> any thread/loop probably has to wait for "child thread/loops" to exit > >>>> before exiting itself (should join all the thread's at a minimum). it > >>>> can hold the exit request pending and keep the loop running until all > >>>> children have reported back to have exited. this does present one > >>>> possible exception - the main loop. should it wait too? that is a good > >>>> question, but definitely all other threads/loops should wait so we end > >>>> up with a nice organized tree of threads/loops or ... tasks that have > >>>> "children" (thread/process thread/task children not object children) > >>>> finish before the parent does so you have a nice guaranteed cleanliness > >>>> by default at least. > >>>> > >>>I think we are getting seriously distracted with all of this threads/loops > >> here. As said above, it is unlikely that we can make that part of our API > >> stable for next release. It would require change in Eo and Eoliand to make > >> binding aware of thread ownership. This would obviously require to make > >> sure > >> > > we need this for c and c++. apparently davemds needs the efl.exe and related > > classes too for python because python doesn't offer a loop integrated async > > stdin/out io to a child executable. > > No, you are mixing two things here. efl.exe and efl thread. I am talking > about threads only here. > > > threads are just extending that python need into what is needed for c/c++ > > anyway. it cleans up a lot and makes threads far nicer to use with symmetric > > i/o to/from a parent as opposed to one-way etc. > > As I have said before no binding will be able to use threads as currently > provided by Eo and Eolian. They have no way to know if an object can be > created in a thread or another. There is nothing that tell when an object can > be transfered to another thread nor how. There is a lot of metadata that > needs to be pushed into .eo files to enable the beginning of threads support > and potentially also fix in Eo domain API. actually not true. c++ will be just fine. but i still don't see why this shouldn't be fleshed out now otherwise we'll end up designing something that is hard to do nicely later. and we want/need this for c (and c++) anyway. forget bindings. E, rage, terminology, ephoto etc. all would want/need this kind of stuff. should they wait for all bindings to have a full runtime to use something nicer for threads? i think not. yes. we need to be able to tag classes as "mainloop only" or not... that's about it actually. objects can't be transferred at all. so that's not an issue. the only thing is "they can be shared between threads". that's the only thing that needs to also be expressed. and what classes of objects are allowed to be shared. another flag like "main loop only". right now we have actually really no objects that can be shared (designed to be able to be)... so it's all moot atm. > > i;m doing this because we need to at least set a baseline on design, without > > which bad things happen that put roadblocks in for the future. we don't > > have to implement everything. i don't plan to implement anything more than > > "stdin/out" style byte streams via the reader/writer interfaces. we could > > add a lot of controls like suspend and resume of a thread from its parent > > etc. ... but no need right now. > > You are confusing me here a lot. This is talking about efl.exe again, not > efl.thread. I don't understand at all what you are planning to do here. i want efl.exe and efl.thread to look the same. they have the same task class to run and end it, the same efl.io.* interface to read/write to them (stdin/out to exe or pipes to threads. both ways like an exe, unlike ecore_thread that was one-way replies only after a thread is created). the more similar things are the easier it is to learn a pattern and re-use it or to move code from threads to exes and back. i am using the efl.io stuff so the same interfaces used for efl.net are re-used. you can use the buffers stream object for example to parse by newlines etc. i talked with k-s about this and got a fair bit of help from him. > >>that language that do have a very different approach to this problematic be > >> able to get the information they need to make binding work. With that > >> constraint in mind, I am pretty certain we have no time to investigate this > >> details for next release and that the only case that matter in the use case > >> for one main loop with the goal of a simpler code for us to maintain also. > >> > > certainly for c/c++ this absolutely does not apply. :) > > C and C++ can continue to use legacy C API for the time being and we do not > need to rush anything for that purpose. then they have to deal with a fairly crufty thread system. the efl.thread, efl.exe etc. thing i have is a lot cleaner and tidier. it's symmetrical for io between net/exe/mainloop+app and thread. i guess it'll make sense when you see examples. > >>If you think it is best to have one object Efl.App that inherit from > >>Efl.Loop > >> and that it will be easy to maintain. Please go ahead and do it. I have no > >> > > i have done it. locally. :) > > Ok, push it then. making it work. not perfect. but work first. i've been working on it. a few more things before landing. i will draw up a design doc too after that. -- ------------- Codito, ergo sum - "I code, therefore I am" -------------- Carsten Haitzler - [email protected] ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ enlightenment-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
