Hi, after some debugging I found out that dillo was frozen because it waits for input on the unix socket from the cookies.dpi. cookies.dpi itself blocks on the read() on the connection socket. If you kill dillo and stop dpid, the next time the cookies.dpi starts, it finds the cookies files locked and terminates immedediately. Then dpid starts the cookies.dpi again and again in an infinite loop. In my theory, the freeze where both processes are hanging in read() is caused when a connection is creating via DEBUG_MSG(5, "Cookies.c: a_Cookies_set \n\t \"%s\" \n",cmd ); a_Capi_dpi_send_cmd(NULL, NULL, cmd, "cookies", 1); but the data is not send yet and /* Get the answer from cookies.dpi */ dpip_tag = a_Dpi_send_blocking_cmd("cookies", cmd); is called. I have attached a patch which uses a_Dpi_send_blocking_cmd(). It seems to fix the problem. dillo has not been frozen again yet. Maybe cookies.dpi should create the SockHandler only when there is data to read (checking for it with select() first). Greetings Andreas Kemnade
Hi Andreas, On Fri, Apr 11, 2008 at 07:42:29PM +0200, Andreas Kemnade wrote:
Hi,
after some debugging I found out that dillo was frozen because it waits for input on the unix socket from the cookies.dpi. cookies.dpi itself blocks on the read() on the connection socket.
If you kill dillo and stop dpid, the next time the cookies.dpi starts, it finds the cookies files locked and terminates immedediately. Then dpid starts the cookies.dpi again and again in an infinite loop.
In my theory, the freeze where both processes are hanging in read() is caused when a connection is creating via DEBUG_MSG(5, "Cookies.c: a_Cookies_set \n\t \"%s\" \n",cmd ); a_Capi_dpi_send_cmd(NULL, NULL, cmd, "cookies", 1);
but the data is not send yet and /* Get the answer from cookies.dpi */ dpip_tag = a_Dpi_send_blocking_cmd("cookies", cmd); is called.
I have attached a patch which uses a_Dpi_send_blocking_cmd(). It seems to fix the problem. dillo has not been frozen again yet. Maybe cookies.dpi should create the SockHandler only when there is data to read (checking for it with select() first).
I have the same patch here! (with a few minor additions). What was really misleading for me, was that the old dillo-0.8.6 has no problem at all with using the non-blocking: a_Capi_dpi_send_cmd(NULL, NULL, cmd, "cookies", 1); So AFAIS it ended being a race-condition problem. This is, the cookie_set command was requested before the cookie_get for the next image, but were answered in the reverse order in dillo2 but not in dillo1! Note: What still puzzles me, is why accept() returns when there's nothing to read. I'll commit to let it have more testing. Thanks for the help.
Index: src/cookies.c =================================================================== RCS file: /sfhome/cvs/dillo/dillo2/src/cookies.c,v retrieving revision 1.4 diff -u -r1.4 cookies.c --- src/cookies.c 24 Feb 2008 22:15:53 -0000 1.4 +++ src/cookies.c 11 Apr 2008 17:41:48 -0000 @@ -155,6 +155,7 @@ }
for (i = 0; (cookie_string = dList_nth_data(cookie_strings, i)); ++i) { + char *dpip_tag; path = URL_PATH_(set_url); snprintf(numstr, 16, "%d", URL_PORT(set_url)); cmd = a_Dpip_build_cmd("cmd=%s cookie=%s host=%s path=%s port=%s", @@ -162,7 +163,10 @@ path ? path : "/", numstr);
DEBUG_MSG(5, "Cookies.c: a_Cookies_set \n\t \"%s\" \n",cmd ); - a_Capi_dpi_send_cmd(NULL, NULL, cmd, "cookies", 1); + dpip_tag = a_Dpi_send_blocking_cmd("cookies", cmd); + if (dpip_tag != NULL) { + dFree(dpip_tag); + } dFree(cmd); } }
-- Cheers Jorge.-
Hi Jorge, On Fri, 11 Apr 2008 15:34:49 -0400 Jorge Arellano Cid <jcid@dillo.org> wrote:
Note: What still puzzles me, is why accept() returns when there's nothing to read.
Hmm, accept() returns when you call connect() on the other side. Many TCP server programs send stuff to the client before receiving anything from the client (like ssh servers, smtp servers) so there is nothing unusual about that. So, normally you have on cookies.dpi side: accept() returns after connect() on dillo side read() returns after write() on dillo side then on dillo side: read() returns after write() on cookies.dpi side. As far as I understand in the race condition case you have: dillo cookies.dpi connect(sock1,...) sock1=accept(....) connect(sock2,...) (via a_Dpi_send_blocking_cmd) read(sock1,...) write(sock2,...) (does not block, contents will be added to the recv queue) read(sock2,...) and now, both sides are waiting for data,.... Greetings Andreas Kemnade
On Fri, Apr 11, 2008 at 11:49:26PM +0200, Andreas Kemnade wrote:
Hi Jorge,
On Fri, 11 Apr 2008 15:34:49 -0400 Jorge Arellano Cid <jcid@dillo.org> wrote:
Note: What still puzzles me, is why accept() returns when there's nothing to read.
Hmm, accept() returns when you call connect() on the other side. Many TCP server programs send stuff to the client before receiving anything from the client (like ssh servers, smtp servers) so there is nothing unusual about that.
So, normally you have on cookies.dpi side: accept() returns after connect() on dillo side read() returns after write() on dillo side
then on dillo side: read() returns after write() on cookies.dpi side.
As far as I understand in the race condition case you have:
dillo cookies.dpi connect(sock1,...) sock1=accept(....) connect(sock2,...) (via a_Dpi_send_blocking_cmd) read(sock1,...) write(sock2,...) (does not block, contents will be added to the recv queue) read(sock2,...)
and now, both sides are waiting for data,....
Thanks a lot for the explanation. -- Cheers Jorge.-
participants (2)
-
akemnade@tzi.de
-
jcid@dillo.org