[FFmpeg-devel] [PATCH 1/5] udp: use pthread_cancel instead of a shared flag.

Nicolas George nicolas.george at normalesup.org
Sat Mar 17 14:40:55 CET 2012


Le sextidi 26 ventôse, an CCXX, Reimar Döffinger a écrit :
> I have some doubts that is portable.
> Will things work nicely when that feature is not supported?

To build up on what I wrote in my other mail, pthread_cancel and related are
standard non-optional features, and recv is amongst the standard
cancellation points since Singne Unix v3 and POSIX.1-2001.

I have looked at the man page of a few Unix on the web, and tested what I
could:

On NetBSD, recv is listed as a cancellation point in
pthread_setcancelstate(3) and it works.

On OpenBSD, recv is not listed as a cancellation point, but read is, and I
could test the patch: it works.

On FreeBSD, same documentation, I could not test.

Same on Darwin, plus its advocates are always bragging it is a
standard-compliant Unix.

Same for Solaris, but getmsg is listed, and AFAIR sockets are implemented on
top of STREAMS.

On the whole, the odds seem pretty good, and since the benefits are quite
interesting (simpler and more efficient), I think we should go on.

> Will it compile when the Windows pthread stub is in use instead
> of full pthreads?

Actually, it is not a problem: this bunch of code is protected by "#if
HAVE_PTHREADS", and the windows pthread stub does not define it:

#define THREADS (HAVE_PTHREADS || (defined(WIN32) && !defined(__MINGW32CE__)))
#if THREADS
#if HAVE_PTHREADS
#include <pthread.h>
#else
#include "libavcodec/w32pthreads.h"
#endif
#endif

As a side note, before I noticed it was not necessary, I asked a friend some
advice, and he showed me a way of emulating pthread_cancel for windows. Here
it is, for future reference (no copyright nor attribution requested).

Regards,

-- 
  Nicolas George


Initialisation:

WSAEVENT ev_cancel = WSACreateEvent();
if (ev_cancel == WSA_INVALID_EVENT)
    fail();
SOCKET fd = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, NULL, 0,
                      WSA_FLAG_OVERLAPPED);
if (fd == INVALID_SOCKET)
    fail();


First thread:

WSABUF b = { blen, buf };
DWORD len, f = 0;
OVERLAPPED ov = { 0 };
ov.hEvent = WSACreateEvent();
if (ov.hEvent == WSA_INVALID_EVENT)
    fail();
if (WSARecv(fd, &b, 1, NULL, &f, &ov, NULL) != 0) {
    WSAEVENT ev[2] = { ov.hEvent, ev_cancel };
    if (WSAGetLastError() != WSA_IO_PENDING)
        fail();
    /* overlapped IO */
    switch (WSAWaitForMultipleEvents(2, ev, FALSE, WSA_INFINITE, FALSE)) {
      case WSA_WAIT_EVENT_0:
        /* IO completed */
        break;
      case (WSA_WAIT_EVENT_0 + 1):
        /* cancelled */
        WSACloseEvent(ov.hEvent);
        _endthreadex(0);
      default:
        fail();
    }
}
if (! WSAGetOverlappedResult(fd, &ov, &len, FALSE, &f))
    fail();


Other thread:

WSASetEvent(ev_cancel);

-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20120317/a0be7fee/attachment.asc>


More information about the ffmpeg-devel mailing list