Here's some code to enable named semaphores as defined in <semaphore.h>.
I've tested it with the libtubo example program and all
seems to work well. The only caveat is that windows will unlink the
semaphore when the last process closes the semaphore. This goes hand in
hand with the inability of windows to unlink a file whilst a process has an
open file descriptor on the file. So you have to be careful not to do the
close on the semaphore before the remote process has a chance to open it.

Support for unnamed semaphore is not yet in the code.

// Semaphore wrappers
#ifdef HAVE_WINDOWS_H
#include <stdarg.h>
#include <sys/types.h>
# define _sem_t int

static
_sem_t *_sem_open(const char *name, int oflag, ...){
    va_list var_args;
    int mode;
    unsigned int value;
    HANDLE handle;
    if (oflag & O_CREAT) {
        va_start(var_args, oflag);
        mode = va_arg(var_args, int);
        value = va_arg(var_args, unsigned int);
        va_end(var_args);
        handle = CreateSemaphore(NULL, (LONG) value, (LONG) 1024, name);
    } else {
        handle = OpenSemaphore( SEMAPHORE_ALL_ACCESS, FALSE, name);
    }
    if (handle == NULL){
        LPTSTR buffer;
        errno = EINVAL;
        return (_sem_t *)SEM_FAILED;
    }
    return (_sem_t *)handle;
}

static int _sem_close(_sem_t *sem){
    if (!sem || sem == SEM_FAILED) {
            errno = EBADF;
            return -1;
    }
    BOOL result = CloseHandle(sem);
    if (!result){
        errno = EINVAL;
        return -1;
    }
    return 0;
}

static int _sem_unlink(const char *name){
    // Windows does this when all processes close the semaphore.
    return 0;
}

static int _sem_post(_sem_t *sem){
   BOOL result = ReleaseSemaphore( sem, 1, NULL);
   if (!result) return -1;
   return 0;
}


static int _sem_timeout(_sem_t *sem, long timeout){
   DWORD result = WaitForSingleObject(sem, timeout);
   switch (result){
      case WAIT_OBJECT_0:
          return 0;
      case WAIT_TIMEOUT:
          return -1;
      case WAIT_FAILED:
          return -1;
   }
}

static int _sem_timedwait(_sem_t *sem, const struct timespec *abs_timeout){
    long milliseconds = abs_timeout->tv_sec * 1000;
    milliseconds += (abs_timeout->tv_nsec/1000000);
    tubo_sem_timeout(sem, milliseconds);
}


#define _sem_wait(X) _sem_timeout(X, INFINITE)
#define _sem_trywait(X) _sem_timeout(X, 0L)

#else
# define _sem_t sem_t
# define _sem_open(...) sem_open(__VA_ARGS__)
# define _sem_close(X)  sem_close(X)
# define _sem_unlink(X) sem_unlink(X)
# define _sem_post(X)   sem_post(X)
# define _sem_wait(X)   sem_wait(X)
# define _sem_trywait(X)   sem_trywait(X)
# define _sem_timedwait(X)   sem_timedwait(X)

#endif



-- 
------------------------------------------------------------------------------------
Dr. Edscott Wilson Garcia
Applied Mathematics and Computing
Mexican Petroleum Institute
------------------------------------------------------------------------------
November Webinars for C, C++, Fortran Developers
Accelerate application performance with scalable programming models. Explore
techniques for threading, error checking, porting, and tuning. Get the most 
from the latest Intel processors and coprocessors. See abstracts and register
http://pubads.g.doubleclick.net/gampad/clk?id=60136231&iu=/4140/ostg.clktrk
_______________________________________________
Mingw-w64-public mailing list
Mingw-w64-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to