libmicrohttpd
[Top][All Lists]
Advanced

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

Re: [libmicrohttpd] minor issue with epoll+externalselect+no_timeout


From: Christian Grothoff
Subject: Re: [libmicrohttpd] minor issue with epoll+externalselect+no_timeout
Date: Thu, 19 Jun 2014 17:35:41 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.5.0

Ah, I see.  Should be fixed in SVN 33735.

Happy hacking!

Christian

On 06/19/2014 09:07 AM, Marcos Pindado Sebastian wrote:
> Hi Christian!,
> 
> I am using version 0.9.34, but to align to the tests you suggest I have 
> downloaded version 0.9.37 and the results are the same.
> 
> Daemon flags: 
> MHD_USE_SUSPEND_RESUME|MHD_USE_DEBUG|MHD_USE_EPOLL_LINUX_ONLY|MHD_USE_EPOLL_TURBO
> 
> Debugging MHD_start_daemon I see setup_epoll_to_listen is called during 
> MHD_start_daemon_va:
> 
> Breakpoint 1, setup_epoll_to_listen (daemon=0x61a010) at daemon.c:3232
> 3232    {
> 
> but the socket_fd is still -1 and this function returns with no error
> 
> 3249      if (MHD_INVALID_SOCKET == daemon->socket_fd)
> 3250        return MHD_YES; /* non-listening daemon */
> (gdb) p daemon->socket_fd
> $1 = -1
> 
> Then again in MHD_start_daemon_va jump to 3550
> 
> 3550      if ( (MHD_INVALID_SOCKET == daemon->socket_fd) &&
> 3551           (0 == (daemon->options & MHD_USE_NO_LISTEN_SOCKET)) )
> (gdb) p daemon->options & MHD_USE_NO_LISTEN_SOCKET
> $2 = 0
> 
> And then creates the socket_fd:
> 
> 3558            socket_fd = create_socket (daemon,
> 3559                                       PF_INET, SOCK_STREAM, 0);
> 
> So setup_listen for this case is called before the socket_fd is set up and it 
> is not attached to the epoll descriptor.
> 
> Invoking MHD_run once after daemon is created, the socket_fd is attached to 
> the epoll:
> 
> 2465      if ( (MHD_INVALID_SOCKET != daemon->socket_fd) &&
> 2466           (0 != daemon->max_connections) &&
> 2467           (MHD_NO == daemon->listen_socket_in_epoll) )
> 2468        {
> 2469          event.events = EPOLLIN;
> 2470          event.data.ptr = daemon;
> 2471          if (0 != epoll_ctl (daemon->epoll_fd,
> 2472                              EPOLL_CTL_ADD,
> 2473                              daemon->socket_fd,
> 
> 
> Thanks!
> 
> Marcos
> ________________________________________
> De: address@hidden address@hidden en nombre de Christian Grothoff 
> address@hidden
> Enviado el: miércoles, 18 de junio de 2014 21:12
> Para: address@hidden
> Asunto: Re: [libmicrohttpd] minor issue with epoll+external     
> select+no_timeout
> 
> Hi!
> 
> Interesting workaround, but obviously this is not how it should be.
> 
> However, I am not sure I can see how this happens.  In daemon.c:3537
> MHD_start_daemon_va() makes a call to 'setup_epoll_to_listen()' and in
> that function in line daemon.c:3253 the listen FD is added to the epoll 
> set..=0A
> For the combination of flags you state, I do not quite see how the
> respective paths would not be taken (without triggering a jump to
> 'free_and_fail' which means MHD_start_daemon() would return NULL).
> 
> So to further understand, analyze and hopefully improve the situation,
> could you say which version of MHD are you using, and --- especially if
> you are using a release >= 0.9.35 --- could you please try to use gdb to
> see how MHD runs through the MHD_start_daemon()-routine without
> triggering the epoll call in line 3253?
> 
> 
> Happy hacking!
> 
> Christian
> 
> On 06/18/2014 11:40 AM, Marcos Pindado Sebastian wrote:
>> Hi,
>>
>> I want to share this little issue I had while implementing an external 
>> select webserver.
>> Case: daemon configured with MHD_USE_EPOLL_LINUX_ONLY plus EXTERNAL_SELECT.
>>
>> The typical example for the external select is:
>>
>> MHD_start_daemon (epoll)
>> while (1)
>>  {
>>    MHD_get_fdset (...)
>>    MHD_get_timeout(...)
>>    select(fds, timeout)
>>    MHD_run
>> }
>>
>> Well, the example worked as far as I noticed that timeout had value 0 (not 
>> null), meaning not waiting at all. When I changed it to NULL then the 
>> example stopped working, because the program got blocked in the select 
>> statement not being notified of incoming connections.
>> The problem is, MHD_start_daemon, creates the epollFD before the 
>> listen-socket is set up. So, get_fdset returns a well epoll-fd without any 
>> listen socket attached just after start_daemon returns.
>>
>> The solution for this is very simple, call MHD_run one time after the daemon 
>> is started and before the select-loop:
>>
>> MHD_start_daemon (epoll)
>> MHD_run // => The listen socket is attached to the epollFD
>> while (1)
>>  {select/run}
>>
>>
>> Thanks for your work!
>> ____________
>> Verificada la ausencia de virus por G Data MailSecurity
>>
>> Versión: AVA 24.2721 del 18.06.2014
>> Noticias de virus: www.antiviruslab.com
>>
> 
> ____________
> Verificada la ausencia de virus por G Data MailSecurity
>  
> Versión: AVA 24.2736 del 19.06.2014 
> Noticias de virus: www.antiviruslab.com
> 



reply via email to

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