On Tue, Aug 16, 2011 at 11:46 AM, Carsten Haitzler <ras...@rasterman.com> wrote: > On Fri, 12 Aug 2011 12:28:51 +0200 Cedric BAIL <cedric.b...@free.fr> said: >> On Fri, Aug 12, 2011 at 11:05 AM, Carsten Haitzler <ras...@rasterman.com> >> wrote: >> > this really should return a handle so you can cancel the call from the >> > thread that queued it. the cancel needs to block if the callback is >> > currently in progress (locks around it) and of course cancel without >> > error. now we need to also know when the thread safe call is done so the >> > thread knows if the handle is valid anymore. >> > >> > why? >> > >> > example. thread queues a threadsafe call to do evas_object_file_Set(obj, >> > file, NULL); fine, this is meant to run in the mainloop some time later. >> > BUT.. then a bit later the thread realizes that the file is invalid or has >> > been deleted and wants to cancel the operation. maybe it wants to free a >> > data struct or object that was passed to the threadsafe callback. we put a >> > fair bit of work on the shoulders of the app then to handle this. we need a >> > way to cancel the operation as its now asynchronous. (what if mainloop >> > deletes the object or canvas the object is in before the async callback can >> > get run? we need more management here). >> >> Of course this kind of issue need to be addressed. I have been using >> this call in emotion for a few week, so here is how I use it. From my >> point of view, we always have a context variable, that hold the >> pointer to object and everything usefull in the main loop. I add to >> this context two int, in and out, and one boolean to know if the >> context need to be destroyed. In the thread I increment out, in the >> main loop at the beginning of the function I increment in. If both are >> equal and the context is marked to be destroyed, then I can destroy >> it. >> >> The reason I am doing that is that I think that the context can't be >> destroyed in the main loop as long as we are not sure that the thread >> are dead or at least informed that the context is being destroyed. As >> we don't have a way to talk to a random thread, the only way is to >> setup a flag and wait for the thread to react on it. >> >> I see the same kind of race condition with cancel. How could you be >> informed safely in your thread that the request has not yet been >> ordered and that you can still cancel it. I didn't saw a way to >> properly design that call. That's why it's a fire and forget call, >> once you send your request, you have no way to interfere with the >> result until it execute in the main loop. It always will and nothing >> can stop it. This simplify a lot the design and make the app >> responsible of what they are doing. >> >> To help apps, maybe we could add this in/out and delete_me mechanism >> generic. But I don't see a way, we could safely and usefully implement >> a cancel behaviour without running into a mess. For this kind of >> double direction call, better switch to a more complex Ecore_Thread >> type, that would be able to discuss in both direction with the main >> loop. I have some patch for that waiting on my hard drive, that I >> should finish. >> >> To get a better idea of this design look after Apple Grand Central >> Dispatch dispatch_async function, >> http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man3/dispatch_async.3.html >> . As you see, they don't have a way to cancel a call once it is >> started. I think I could add a synchronous version, by using >> cond_wait, if it make sense to anyone and people see it usefull. > > i think a sync version sounds like a sensible idea. it will simplify things a > LOT.... in fact.. what you want is a lock-step system so u dont even need to > fire-and-forget a callback like: > > ecore_thread_main_loop_begin(); > // do all efl mainloop stuff here - ecore, evas, etc. > evas_object_show(obj); > // etc.... > ecore_thread_main_loop_end(); > > so in this case, ecore_thread_main_loop_begin(); will send off a req via pipe > to "wait" and then the call blocks and waits for the mainloop to hit this > wait... the wait just uses a cond_wait on the mainloop side and int he call. > the mainloop just triggers the condition and then the mainloop in tern waits > for ecore_thread_main_loop_end(); to be called when its condition is triggered > by the thread and then continues running. > > this is much a very simple way of EFFECTIVELY running code inside the mainloop > simply by guaranteeing the mainloop is at a "normal execution state but > suspended waiting to be released". sure the thread has to wait - but that's > life. > > this totally removes the need to cancel. well as long as resources the thread > will use are not deleted while it's waiting...
I am almost done with the sync version. I dislike the idea of completly locking the main loop for a random amount of time, but it seems to me that it will be the least annoying way to get the so called "thread safety" things in, so I think I will implement that after the sync function. I personnally really prefer using sync and async call in the main loop, and I think that we should just advertise this way of doing things, but anyway I will do that ecore_threads_main_loop_begin things. -- Cedric BAIL ------------------------------------------------------------------------------ uberSVN's rich system and user administration capabilities and model configuration take the hassle out of deploying and managing Subversion and the tools developers use with it. Learn more about uberSVN and get a free download at: http://p.sf.net/sfu/wandisco-dev2dev _______________________________________________ enlightenment-devel mailing list enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel