libmicrohttpd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [libmicrohttpd] shutdown of listen socket does not work on solaris 1


From: Will Bryant
Subject: Re: [libmicrohttpd] shutdown of listen socket does not work on solaris 10
Date: Mon, 19 Sep 2011 00:25:40 +1200

That sounds workable.

I'd be a little reluctant to sprinkle lists of platforms in ifdefs throughout 
the project - we'd be too likely to miss one bit of code when adding a new 
platform to the list.  So should we set a conditional define, say 
HAVE_LISTEN_SHUTDOWN, and if it's not set we run the old pipe code?  And set 
this based on the platform somewhere in the autotools stuff?

I presume the cygwin target can use the pipe solution too, as a brief google 
suggests it has a working pipe().


On 19/09/2011, at 00:18 , Christian Grothoff wrote:

> I see.  But given that on Linux it works without a pipe and that a pipe also 
> "consumes" two extra FDs, I think the answer should be slightly different: 
> revert 14584 *conditionally* for non-Linux, non-FreeRTOS OSes.  So we'd have 
> pipes on Solaris/*BSD/OS X, and no-pipes on Linux/FreeRTOS.  That should make 
> everyone happy (at the expense of a few additional #ifdef's in the code, a 
> price we can probably pay, right?).
> 
> Now, I won't have time to do this today, but I do take patches along these 
> lines ;-).
> 
> Happy hacking,
> 
> Christian
> 
> On 09/18/2011 01:13 AM, Will Bryant wrote:
>> Coincidentally I discovered the same problem on Mac OS X last night, while 
>> trying to debug issue #1760.  There we had noticed that the shutdown call 
>> was failing and I had also noticed that my app does not shut down ever since 
>> I upgraded past 0.9.7, and the library's tests were not running properly.
>> 
>> It turns out that libmicrohttpd has been failing tests (well, they hang 
>> rather than failing) on OS X ever since 0.9.8.  I did a bisect to find the 
>> offending commit and found it was r14584, "also eliminating use of pipe, 
>> thereby addressing #1662".
>> 
>> So basically because the original requestor on FreeRTOS couldn't use pipe(), 
>> a solution has been adopted that I believe doesn't work on many unixes other 
>> than Linux - it's definitely broken on OS X and Solaris, and my 
>> understanding from #1674 is that it was also broken on Cygwin - though the 
>> #1674 workaround which has been committed presumably works on cygwin but 
>> doesn't seem to work on OS X when I try it.
>> 
>> Can anyone confirm if shutdown still works on the BSDs?  I would have 
>> guessed not since OS X tends to be closer to the BSD behavior.
>> 
>> I agree with Christian that using close() on the socket is not an acceptable 
>> solution due to the race condition.
>> 
>> I personally think that the best thing to do would be to revert the r14584 
>> commit to start with, because the pipe solution was a good one for most 
>> supported platforms, and if the FreeRTOS support is still required, let the 
>> requestor work on another solution for platforms missing most of the posix 
>> spec (it could use a localhost socket pair, for example) or patch the 
>> library to use the shutdown technique on that platform only.
>> 
>> Adding complicated workarounds for platforms that don't have many basic OS 
>> features seems like an unfair burden on libmicrohttpd.
>> 
>> 
>> On 16/09/2011, at 11:53 PM, Frank Meier wrote:
>> 
>>> hi
>>> 
>>> I tried to use libmicrohttpd on solaris 10, and my simple programm only 
>>> starting and stopping the daemon (see below) did hang in.
>>> after some investigation (see debug code) I found, that the shutdown call 
>>> in daemon.c fails, since the daemon socket is not a connected fullduplex 
>>> but a listening socket. this means the daemon thread keeps hanging in 
>>> select() and main hangs in pthread_join() (see pstack output). problem is 
>>> since the socket doesn't get closed, select does not interrupt. After 
>>> adding CLOSE (fd) after the point of SHUTDOWN () the programm did work. It 
>>> looks like solaris and linux behave differently when shutdown is called on 
>>> a listening socket. But on the other hand I'm not sure if it is correct to 
>>> call shutdown in the first place, since the man page states "The  
>>> shutdown() call causes all or part of a full-duplex connection on the 
>>> socket associated with sockfd to be shut down" and the listening socket 
>>> does not have a connection.
>>> 
>>> I think the socket should be closed with CLOSE before calling 
>>> pthread_join() and use SHUTDOWN only on connection sockets.
>>> 
>>> regards, Frank
>>> 
>>> 
>>> /*test programm*/
>>> struct MHD_Daemon* mhdDaemon = 0;
>>> mhdDaemon = MHD_start_daemon (MHD_USE_THREAD_PER_CONNECTION, mhdPort, NULL, 
>>> NULL,&answer_to_connection, NULL, MHD_OPTION_END);
>>> if (mhdDaemon)
>>> {
>>>    MHD_stop_daemon (mhdDaemon);  //<-here it hangs
>>>    mhdDaemon = 0;
>>> }
>>> 
>>> /*debug code in daemon.c*/
>>> --- daemon/daemon.c     (revision 16873)
>>> +++ daemon/daemon.c     (working copy)
>>> @@ -2477,7 +2477,11 @@
>>>       daemon->worker_pool[i].shutdown = MHD_YES;
>>>       daemon->worker_pool[i].socket_fd = -1;
>>>     }
>>> -  SHUTDOWN (fd, SHUT_RDWR);
>>> +       int res = SHUTDOWN (fd, SHUT_RDWR);
>>> +       int tmpErrno = errno;
>>> +       printf("shutdown res:%d  %s\n", res, strerror(tmpErrno));
>>> +
>>> +       CLOSE (fd);
>>> 
>>> ->output with debug code:
>>> shutdown res:-1  Transport endpoint is not connected
>>> 
>>> /*pstack output ->  damon thread is in select, main hangs in pthread join*/
>>> $ pstack 16802
>>> 16802:  ./test.bin
>>> -----------------  lwp# 1 / thread# 1  --------------------
>>> feee9365 lwp_wait (2, 80478d8)
>>> feee2c1f _thrp_join (2, 0, 8047918, 1) + 5a
>>> feee2d9e pthread_join (2, 8047918, feeec7e0, fef9665d) + 2b
>>> fef96777 MHD_stop_daemon (8060d40, 0, 0, fee63301) + 12b
>>> 0805080a main     (1, 8047988, 8047990) + 6f
>>> 080506ac _start   (1, 8047a88, 0, 8047a93, 8047abe, 8047b78) + 60
>>> -----------------  lwp# 2 / thread# 2  --------------------
>>> feee8da5 pollsys  (fed5ed50, 1, 0, 0)
>>> fee93afa pselect  (4, fed5ef30, fed5eeb0, fed5ee30, 0, 0) + 18e
>>> fee93df0 select   (4, fed5ef30, fed5eeb0, fed5ee30, 0, 0) + 82
>>> fef95ba4 MHD_select (fec50200, fec50200, fed5efec, feee59b9, 8060d40, 0) + 
>>> 130
>>> fef96248 MHD_select_thread (8060d40) + 18
>>> feee59b9 _thr_setup (fec50200) + 4e
>>> feee5ca0 _lwp_start (fec50200, 0, 0, fed5eff8, feee5ca0, fec50200)
>> 
>> 
> 
> 




reply via email to

[Prev in Thread] Current Thread [Next in Thread]