[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