I'm currently working on a bug in Chilimoon. The problem is we're getting the following error messages:
Backend already in use by another thread. _static_modules.Builtin()->Backend: Pike.Backend(0)->`()("Backend already in use by another thread.\n")
This error comes from backend.cmod. After doing some research I've discovered the bug occurs after an cvs checkin of backend.cmod in pike on 2005-01-20. r1.161 is working, r1.163 isn't.
It might be possible this checkin breaks the shuffler which is used by Chilimoon, and not by Roxen Webserver. Roxen Webserver does not have the same problem.
Sorry to reply to myself,
It breaks at r1.62 of backend.cmod
On Wed, Jun 29, 2005 at 01:36:50AM +0200, Marc Dirix wrote:
I'm currently working on a bug in Chilimoon. The problem is we're getting the following error messages:
Backend already in use by another thread. _static_modules.Builtin()->Backend: Pike.Backend(0)->`()("Backend already in use by another thread.\n")
This error comes from backend.cmod. After doing some research I've discovered the bug occurs after an cvs checkin of backend.cmod in pike on 2005-01-20. r1.161 is working, r1.163 isn't.
It might be possible this checkin breaks the shuffler which is used by Chilimoon, and not by Roxen Webserver. Roxen Webserver does not have the same problem.
Included is a minimal diff, that after applying results in the bug.
Grubba, any idea why your change appears to break the Shuffler?
This is the patch:
=== backend.cmod ================================================================== --- backend.cmod (revision 33705) +++ backend.cmod (local) @@ -5,7 +5,7 @@ */
/* - * $Id: backend.cmod,v 1.161 2005/01/20 14:17:51 grubba Exp $ + * $Id: backend.cmod,v 1.160 2005/01/19 19:32:59 grubba Exp $ * * Backend object. */ @@ -2711,8 +2711,6 @@ { int fd = GET_FD(ACTIVE_POLLSET[i]); struct fd_callback_box *box; - ONERROR uwp; - struct object *ref_obj;
if (!(box = SAFE_GET_ACTIVE_BOX (me, fd))) { /* The box is no longer active. */ @@ -2722,10 +2720,7 @@ check_box (box, fd);
/* Make sure we don't lose the box during some callback. */ - if ((ref_obj = box->ref_obj)) { - add_ref(ref_obj); - SET_ONERROR(uwp, do_free_object, ref_obj); - } + if (box->ref_obj) add_ref(box->ref_obj);
if (box->revents & PIKE_BIT_FD_ERROR) { /* Error */ @@ -2757,7 +2752,7 @@ "[%d]BACKEND[%d]: error event on fd %d sent to %p\n" , getpid(), me->id, i, box->ref_obj)); if (box->callback (box, PIKE_FD_ERROR) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } } @@ -2767,7 +2762,7 @@ "[%d]BACKEND[%d]: read_callback(%d, %p) for error %d \n", getpid(), me->id, fd, box->ref_obj, errno)); if (box->callback (box, PIKE_FD_READ) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } } else if (old_events & PIKE_BIT_FD_WRITE) { @@ -2775,19 +2770,19 @@ "[%d]BACKEND[%d]: write_callback(%d, %p) for error %d\n", getpid(), me->id, fd, box->ref_obj, errno)); if (box->callback (box, PIKE_FD_WRITE) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } } /* Don't call any other callbacks for this fd. */
- if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); continue; }
if (!(box->events & box->revents)) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); continue; }
@@ -2802,7 +2797,7 @@ getpid(), me->id, fd, box->ref_obj)); errno = 0; if (box->callback (box, PIKE_FD_READ_OOB) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } } @@ -2815,7 +2810,7 @@ getpid(), me->id, fd, box->ref_obj)); errno = 0; if (box->callback (box, PIKE_FD_READ) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } } @@ -2825,7 +2820,7 @@ getpid(), me->id, fd, box->ref_obj)); errno = 0; if (box->callback (box, PIKE_FD_WRITE_OOB) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } } @@ -2838,12 +2833,12 @@ getpid(), me->id, fd, box->ref_obj)); errno = 0; if (box->callback (box, PIKE_FD_WRITE) == -1) { - if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); goto backend_round_done; } }
- if (ref_obj) CALL_AND_UNSET_ONERROR(uwp); + if (box->ref_obj) free_object(box->ref_obj); }
#endif /* USE_SELECT */
I think you need to concentrate on what really is the problem instead, since what you've narrowed down there is a fix for another bug that somehow hides the bug you're experiencing.
The bug being fixed there is that refs to the fd/shuffler objects no longer gets lost when an error is thrown through the backend. Without it you got leaked objects (presumably shuffler objects since WebServer isn't affected).
Are you sure the error isn't legitimate? Have you checked the threads involved? I'd start with finding out which thread the backend think is running it, and see what that thread really is doing.
pike-devel@lists.lysator.liu.se