Re: [E-devel] [EGIT] [core/efl] master 01/01: ecore: handle recursive trigger of promise by the cancel of a future.
Hi Cedric, You can still trigger an infinite loop with my new code to trigger timeout due inactivity in efl_io_copier. Use the same test, just give it a timeout: terminal1$ ./src/examples/ecore/efl_net_server_example tcp 0.0.0.0: -t 5.0 terminal2$ telnet 127.0.0.1 and wait for 5 seconds, the client will be timed out and will enter an infinite loop: INFO: client '127.0.0.1:43342' timed out recv, delete it. INFO: recv from 127.0.0.1:43342 0 bytes: --BEGIN RECV DATA-- --END RECV DATA-- INFO: receive copier done, check if should close 0x4000d9e71d5a INFO: client 127.0.0.1:43342 can_write=0 INFO: client 127.0.0.1:43342 eos. INFO: client 127.0.0.1:43342 closed. ERR<14048>:ecore lib/ecore/efl_promise.c:337 _efl_loop_future_cancel() Triggering cancel on an already fulfilled Efl.Future. The hierarchy is similar to above, but the "efl_io_close()" is triggered from a job. On Thu, Oct 20, 2016 at 6:42 PM, Gustavo Sverzut Barbieri wrote: > Hi Cedric, > > It doesn't fix the problem, now there is an infinite loop: > > 1681 while (pd->ext && ext->futures) > (gdb) n > 1682 efl_future_cancel(eina_list_data_get(ext->futures)); > > > I'm testing it with: > > terminal1$ ./src/examples/ecore/efl_net_server_example tcp 0.0.0.0: > > terminal2$telnet 127.0.0.1 > > this will print Hello World in the telnet terminal (#2) and won't > close the connection. In terminal 1 you see it gets stuck, you need to > kill it hard (-9). > > > terminal1, if executed with EINA_LOG_LEVEL=4 says: > > INFO: using sender buffer 0x400086f33b1e with copier > 0x40008ef33b20 for client 127.0.0.1:37364 > ... > INFO: send copier done, check if should close 0x40008ef33b20 > DBG<24279>:ecore lib/ecore/efl_io_copier.c:685 > _efl_io_copier_efl_object_destructor() copier={0x40008ef33b20 > Efl_Io_Copier, refs=0, closed=0, done=1, buf=0} > DBG<24279>:ecore lib/ecore/efl_io_copier.c:685 > _efl_io_copier_efl_object_destructor() source={0x400086f33b1e > Efl_Io_Buffer, refs=1, can_read=0, eos=1, closed=0} > DBG<24279>:ecore lib/ecore/efl_io_copier.c:685 > _efl_io_copier_efl_object_destructor() destination={0x400082f33b1d > Efl_Net_Socket_Tcp, refs=4, can_write=0, closed=0} > DBG<24279>:eo lib/eo/eo_base_class.c:1634 _efl_object_destructor() > 0x400086f33b1e - Efl_Io_Buffer. > DBG<24279>:eo lib/eo/eo_base_class.c:1634 _efl_object_destructor() > 0x40008ef33b20 - Efl_Io_Copier. > > that is, the sender is done and it's deleted from: > > _send_copier_done() > _send_recv_done() > efl_del() > > > what the server does is: > > - for a client, create an efl_io_buffer with "Hello World" string and > and efl_io_copier (send_copier) to send this to the efl_net_socket_tcp > that is created for that client. and an efl_io_buffer + efl_io_copier > to receive (recv_copier). > > - copier will keep a job (efl_future) when can_read/can_write. > > - from job callback it may call user (ie: > _send_copier_done()/_send_recv_done()), which can delete the copier, > that in turn will delete the job that is being dispatched. > > > > > On Wed, Oct 19, 2016 at 6:43 PM, Cedric BAIL wrote: >> Hi Gustavo, >> >> On Tue, Oct 18, 2016 at 4:59 PM, Gustavo Sverzut Barbieri >> wrote: >>> Tried this fix for efl_net_server_example and it doesn't fix the >>> problem, instead it stops crashes but enters an infinite loop: >>> >>> ERR<17134>:ecore lib/ecore/efl_promise.c:301 _efl_loop_future_cancel() >>> Triggering cancel on an already fulfilled Efl.Future. >> >> Can you try fb1feee480270c3e0e556774fc4ee613c82c7dba ? >> >>> since it's now expected that the promise will NULL-ify the pointer >>> once its done, this must be done earlier as well, otherwise my pd->job >>> (efl_io_copier.c) will still use that in its destructor. >> >> Yes and it really should. The problem with this is that I now need to >> fully override in all case weak ref. I think this is the last blow on >> using eo object for future, if I need to reimplement even the minimal >> set of feature as they don't match. I think I will move away from eo >> object before we freeze 1.19, but after we merge eo, ecore and efl >> interface. >> -- >> Cedric BAIL >> >> -- >> 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 >> enlightenment-devel@lists.sourceforge.net >> https://lists.sourceforge.net/lists/listinfo/enlightenment-devel > > > > -- > Gustavo Sverzut Barbieri > -- > Mobile: +55 (16) 99354-9890 -- Gustavo Sverzut Barbieri -- Mobile: +55 (16) 99354-9890 -- Check out the vibrant tech community on one of the world's most engaging tech sites, SlashDot.org! http://sdm.link/s
Re: [E-devel] [EGIT] [core/efl] master 01/01: ecore: handle recursive trigger of promise by the cancel of a future.
Hi Cedric, It doesn't fix the problem, now there is an infinite loop: 1681 while (pd->ext && ext->futures) (gdb) n 1682 efl_future_cancel(eina_list_data_get(ext->futures)); I'm testing it with: terminal1$ ./src/examples/ecore/efl_net_server_example tcp 0.0.0.0: terminal2$telnet 127.0.0.1 this will print Hello World in the telnet terminal (#2) and won't close the connection. In terminal 1 you see it gets stuck, you need to kill it hard (-9). terminal1, if executed with EINA_LOG_LEVEL=4 says: INFO: using sender buffer 0x400086f33b1e with copier 0x40008ef33b20 for client 127.0.0.1:37364 ... INFO: send copier done, check if should close 0x40008ef33b20 DBG<24279>:ecore lib/ecore/efl_io_copier.c:685 _efl_io_copier_efl_object_destructor() copier={0x40008ef33b20 Efl_Io_Copier, refs=0, closed=0, done=1, buf=0} DBG<24279>:ecore lib/ecore/efl_io_copier.c:685 _efl_io_copier_efl_object_destructor() source={0x400086f33b1e Efl_Io_Buffer, refs=1, can_read=0, eos=1, closed=0} DBG<24279>:ecore lib/ecore/efl_io_copier.c:685 _efl_io_copier_efl_object_destructor() destination={0x400082f33b1d Efl_Net_Socket_Tcp, refs=4, can_write=0, closed=0} DBG<24279>:eo lib/eo/eo_base_class.c:1634 _efl_object_destructor() 0x400086f33b1e - Efl_Io_Buffer. DBG<24279>:eo lib/eo/eo_base_class.c:1634 _efl_object_destructor() 0x40008ef33b20 - Efl_Io_Copier. that is, the sender is done and it's deleted from: _send_copier_done() _send_recv_done() efl_del() what the server does is: - for a client, create an efl_io_buffer with "Hello World" string and and efl_io_copier (send_copier) to send this to the efl_net_socket_tcp that is created for that client. and an efl_io_buffer + efl_io_copier to receive (recv_copier). - copier will keep a job (efl_future) when can_read/can_write. - from job callback it may call user (ie: _send_copier_done()/_send_recv_done()), which can delete the copier, that in turn will delete the job that is being dispatched. On Wed, Oct 19, 2016 at 6:43 PM, Cedric BAIL wrote: > Hi Gustavo, > > On Tue, Oct 18, 2016 at 4:59 PM, Gustavo Sverzut Barbieri > wrote: >> Tried this fix for efl_net_server_example and it doesn't fix the >> problem, instead it stops crashes but enters an infinite loop: >> >> ERR<17134>:ecore lib/ecore/efl_promise.c:301 _efl_loop_future_cancel() >> Triggering cancel on an already fulfilled Efl.Future. > > Can you try fb1feee480270c3e0e556774fc4ee613c82c7dba ? > >> since it's now expected that the promise will NULL-ify the pointer >> once its done, this must be done earlier as well, otherwise my pd->job >> (efl_io_copier.c) will still use that in its destructor. > > Yes and it really should. The problem with this is that I now need to > fully override in all case weak ref. I think this is the last blow on > using eo object for future, if I need to reimplement even the minimal > set of feature as they don't match. I think I will move away from eo > object before we freeze 1.19, but after we merge eo, ecore and efl > interface. > -- > Cedric BAIL > > -- > 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 > enlightenment-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/enlightenment-devel -- Gustavo Sverzut Barbieri -- Mobile: +55 (16) 99354-9890 -- 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 enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
Re: [E-devel] [EGIT] [core/efl] master 01/01: ecore: handle recursive trigger of promise by the cancel of a future.
Hi Gustavo, On Tue, Oct 18, 2016 at 4:59 PM, Gustavo Sverzut Barbieri wrote: > Tried this fix for efl_net_server_example and it doesn't fix the > problem, instead it stops crashes but enters an infinite loop: > > ERR<17134>:ecore lib/ecore/efl_promise.c:301 _efl_loop_future_cancel() > Triggering cancel on an already fulfilled Efl.Future. Can you try fb1feee480270c3e0e556774fc4ee613c82c7dba ? > since it's now expected that the promise will NULL-ify the pointer > once its done, this must be done earlier as well, otherwise my pd->job > (efl_io_copier.c) will still use that in its destructor. Yes and it really should. The problem with this is that I now need to fully override in all case weak ref. I think this is the last blow on using eo object for future, if I need to reimplement even the minimal set of feature as they don't match. I think I will move away from eo object before we freeze 1.19, but after we merge eo, ecore and efl interface. -- Cedric BAIL -- 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 enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel
Re: [E-devel] [EGIT] [core/efl] master 01/01: ecore: handle recursive trigger of promise by the cancel of a future.
Hi Cedric, Tried this fix for efl_net_server_example and it doesn't fix the problem, instead it stops crashes but enters an infinite loop: ERR<17134>:ecore lib/ecore/efl_promise.c:301 _efl_loop_future_cancel() Triggering cancel on an already fulfilled Efl.Future. since it's now expected that the promise will NULL-ify the pointer once its done, this must be done earlier as well, otherwise my pd->job (efl_io_copier.c) will still use that in its destructor. On Tue, Oct 18, 2016 at 9:49 PM, Cedric BAIL wrote: > cedric pushed a commit to branch master. > > http://git.enlightenment.org/core/efl.git/commit/?id=efda7d492d55b2117bdc29d5c03f03fc1a32db3a > > commit efda7d492d55b2117bdc29d5c03f03fc1a32db3a > Author: Cedric BAIL > Date: Tue Oct 18 16:49:04 2016 -0700 > > ecore: handle recursive trigger of promise by the cancel of a future. > > This avoid double free/double callback call. > --- > src/lib/ecore/efl_promise.c | 10 +++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/src/lib/ecore/efl_promise.c b/src/lib/ecore/efl_promise.c > index 4bc7496..aa59b8b 100644 > --- a/src/lib/ecore/efl_promise.c > +++ b/src/lib/ecore/efl_promise.c > @@ -139,11 +139,16 @@ static void > _efl_loop_future_propagate(Eo *obj, Efl_Loop_Future_Data *pd) > { > Efl_Event ev; > + Eina_Bool cancel; > > ev.object = obj; > + cancel = pd->fulfilled && !pd->message; > > - if (pd->fulfilled && > - !pd->message) > + // This has to be done early on to avoid recursive success/failure to > + // bypass the fulfilled check. > + pd->fulfilled = EINA_TRUE; > + > + if (cancel) > { > _efl_loop_future_failure(&ev, pd, EINA_ERROR_FUTURE_CANCEL); > } > @@ -155,7 +160,6 @@ _efl_loop_future_propagate(Eo *obj, Efl_Loop_Future_Data > *pd) > { > _efl_loop_future_failure(&ev, pd, pd->message->error); > } > - pd->fulfilled = EINA_TRUE; > > if (!pd->delayed) > { > > -- > > -- Gustavo Sverzut Barbieri -- Mobile: +55 (16) 99354-9890 -- 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 enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel