Here's the code for using named and unnamed semaphores in Mingw-w64. The
only function I have not tested (but looks OK now) is _sem_timedwait().

Code is included in libtubo release 5.0.12 (http://xffm.org/libtubo.html)
with GPLV3, so if it is of any use, feel free to use it. I've prepared
Mingw-w64 7z package at download site too.


// Copyright 2000-2013(C)  Edscott Wilson Garcia under GNU GPLv3
#ifdef DEBUG_TRACE
# define TRACE(...)   \
    { \
    fprintf(stderr, "TRACE:");\
    fprintf(stderr, __VA_ARGS__); \
    fflush(stderr);\
   }
#else
# define TRACE(...)   { (void)0; }
#endif

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

#ifndef SEM_FAILED
#define SEM_FAILED ((_sem_t *)(-1))
#endif
#ifndef SEM_VALUE_MAX
#define SEM_VALUE_MAX 1024
#endif

static
_sem_t *_sem_open(const char *name, int oflag, ...){
    va_list var_args;
    int mode;
    unsigned int value;
    TRACE("--> _sem_open(%s)\n", name);
    _sem_t *sem = (_sem_t *)malloc(sizeof(_sem_t));
    if (!sem) {
            fprintf(stderr, "*** Tubo: malloc(%d): %s\n",
                    sizeof(_sem_t),strerror(errno));
            return (_sem_t *)SEM_FAILED;
    }

    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) SEM_VALUE_MAX,
name);
    } else {
        handle = OpenSemaphore( SEMAPHORE_ALL_ACCESS, FALSE, name);
    }
    if (handle == NULL){
      TRACE("--> %s semaphore %s failed.\n", (oflag &
O_CREAT)?"Create":"Open", name);
        errno = EINVAL;
        free(sem);
        return (_sem_t *)SEM_FAILED;
    }
    TRACE ("--> %s semaphore %s (%d) OK!\n", (oflag &
O_CREAT)?"Create":"Open", name,
                    (intptr_t)handle);
    *sem = handle;
    return sem;
}

static
int _sem_init(_sem_t *sem, int pshared, unsigned int value){
    HANDLE handle = CreateSemaphore(NULL, (LONG) value, (LONG)
SEM_VALUE_MAX, NULL);
    if (handle == NULL) {
            fprintf(stderr, "*** Tubo: Error in CreateSemaphore: %d\n",
GetLastError());
            return -1;
    }
    TRACE("--> _sem_open(unnamed) got %d initialized to %d\n",
(intptr_t)handle, value);
    SetHandleInformation(handle, HANDLE_FLAG_PROTECT_FROM_CLOSE,
HANDLE_FLAG_PROTECT_FROM_CLOSE);

    *sem = handle;

    return 0;
}

static
int _sem_close(_sem_t *sem){
    TRACE("closing semaphore %d\n", *sem);
    if (!sem || sem == SEM_FAILED) {
            errno = EBADF;
            return -1;
    }
    DWORD dwFlags;
    GetHandleInformation(*sem, &dwFlags);
    int unnamed = 0;
    if (dwFlags & HANDLE_FLAG_PROTECT_FROM_CLOSE) {
        unnamed = 1;
        SetHandleInformation(*sem, HANDLE_FLAG_PROTECT_FROM_CLOSE, 0);
    }

    BOOL result = CloseHandle(*sem);
    if (!result){
        errno = EINVAL;
        return -1;
    }

    // If it is a named semaphore, we must free allocated memory.
    if (!unnamed) {
        TRACE("Free sem %d now\n", *sem);
        free(sem);
    } else TRACE("Will not free sem  %d (unnamed)\n", *sem);
    return 0;
}

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

static
int _sem_post(_sem_t *sem){
   TRACE("Releasing semaphore %d\n", *sem);
   BOOL result = ReleaseSemaphore( *sem, 1, NULL);
   if (!result) return -1;
   return 0;
}


static
int _sem_timeout(_sem_t *sem, long timeout){
   TRACE("Wait on semaphore %d\n", *sem);
   DWORD result = WaitForSingleObject(*sem, timeout);
   switch (result){
      case WAIT_OBJECT_0:
          TRACE("Wait OK on semaphore %d\n", *sem);
          return 0;
      case WAIT_TIMEOUT:
          TRACE("Wait timed out on semaphore %d\n", *sem);
          return -1;
      case WAIT_FAILED:
          TRACE("Wait failed on semaphore %d\n", *sem);
          return -1;
   }
}


static
int _sem_timedwait(_sem_t *sem, const struct timespec *abs_timeout){
    struct timeval tv;
    if (gettimeofday(&tv, NULL) < 0) return -1;
    time_t seconds = abs_timeout->tv_sec - tv.tv_sec;
    long milliseconds = seconds * 1000;
    long microseconds =  (abs_timeout->tv_nsec / 1000) - tv.tv_usec;

    milliseconds += (microseconds/1000);
    return 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_init(X,Y,Z) sem_init(X,Y,Z)
# define _sem_trywait(X)   sem_trywait(X)
# define _sem_timedwait(X)   sem_timedwait(X)

#endif





2013/11/11 Edscott Wilson <edscott.wilson.gar...@gmail.com>

>
>
>
> 2013/11/9 dw <limegreenso...@yahoo.com>
>
>>        handle = CreateSemaphore(NULL, (LONG) value, (LONG) 1024, name);
>>
>>
>> Why 1024?  Is this the same as SEM_VALUE_MAX?
>>
>
> Probably not the same. I'm now changing it to  SEM_VALUE_MAX.
>
>
>>
>>      if (handle == NULL){
>>         LPTSTR buffer;
>>         errno = EINVAL;
>>         return (_sem_t *)SEM_FAILED;
>>     }
>>
>>
>> What's the "buffer" for?
>>
>
>
> Missed that on cleanup. It was there for debugging purposes but now is
> useless.
>
>
>>
>>
>>  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);
>> }
>>
>>
>> This doesn't appear to match the man 
>> page<http://man7.org/linux/man-pages/man3/sem_wait.3.html>I read: "If the 
>> timeout has already expired by the time of the call"
>> implies that an absolute time is being specified, not a duration.  While I
>> think your definition is more useful, this may result in unexpected
>> behavior for others.
>>
>
> Right. An absolute time is better to keep things consistent. As soon as I
> put in the code to support unnamed semaphores, I'll post the corrected code
> to the list.
>
> Thanks for your comments!
>
>
>
>
> ------------------------------------------------------------------------------------
> Dr. Edscott Wilson Garcia
> Applied Mathematics and Computing
> Mexican Petroleum Institute
>



-- 
------------------------------------------------------------------------------------
Dr. Edscott Wilson Garcia
Applied Mathematics and Computing
Mexican Petroleum Institute
------------------------------------------------------------------------------
DreamFactory - Open Source REST & JSON Services for HTML5 & Native Apps
OAuth, Users, Roles, SQL, NoSQL, BLOB Storage and External API Access
Free app hosting. Or install the open source package on any LAMP server.
Sign up and see examples for AngularJS, jQuery, Sencha Touch and Native!
http://pubads.g.doubleclick.net/gampad/clk?id=63469471&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