[gnutls-devel] Waiting for input data

Jaak Ristioja jaak.ristioja at cyber.ee
Fri Feb 8 14:42:16 CET 2013


Hi!

On 05.02.2013 18:49, Jouko Orava wrote:
> On Tue, 5 Feb 2013, Jaak Ristioja wrote:
>> I want my thread to sleep (most of the time) until either (1) data
>> becomes available or (2) another thread signals the thread to stop
>> waiting for any data.
> 
> Have you simply set the socket descriptor to nonblocking?
> 	fcntl(sd, F_SETFL, O_NONBLOCK);

Yes.

> At a quick look, GnuTLS should return GNUTLS_E_AGAIN if there is no data
> pending on a nonblocking socket [so underlying recv() returns EAGAIN].
> 
> You can use select()/epoll()/etc. on the socket
> descriptor (sd) to check if there might be data available
> (gnutls_record_recv() may still return GNUTLS_E_AGAIN).


> Another option is to keep the socket blocking, but use an empty-body
> signal handler to interrupt the gnutls_record_recv(), i.e. via
> 	pthread_kill(thread, signum);
> or
> 	pthread_sigqueue(thread, signum, value);
> 
> The delivery of the signal to the target thread will interrupt blocking
> I/O calls; the body of the signal handler can be empty.
> 
> Note, however, that gnutls_record_recv() may return with data even if the
> signal was fired, if sufficient data arrives in a big enough clump.
> That means you must not rely on always noticing the signal (by receiving
> an error from gnutls_record_recv()); you must have a secondary flag
> (semaphore, or atomic flag) to indicate that there is extra processing
> needed to be done.

Hmm... no thanks. Messing with signals is complicated at least.

I think the main issue is that GnuTLS does not provide functions alike
poll/select. I can't poll for data available without reading it. I think
gnutls_record_check_pending should try to receive data from the
underlying transport!

FYI, the following does not work:

  while (!needToStop() && gnutls_record_check_pending(session) <= 0)
    sleepMs(5);

But it would greatly simplify using GnuTLS if it did do so.

I haven't tried to call gnutls_record_recv(session, NULL, 0u)... would
calling it before each gnutls_record_check_pending call make the example
above work? I don't see anything about this mentioned in the documentation.

Best regards,
Jaak



More information about the Gnutls-devel mailing list