BaseGDL* sem_create(EnvT *e)
  {
    SizeT nParam = e->NParam(1); // 1 is the minimal number of parameter required

    DString name;
    e->AssureStringScalarPar(0, name); // IDL accepts null-string name

    int destroyIx = e->KeywordIx("DESTROY_SEMAPHORE");
    bool destroyKWPresent = e->KeywordPresent(destroyIx);
    DLong destroy = 0;
    if (destroyKWPresent) 
    {
      destroy = (*e->GetKWAs<DLongGDL>(0))[0];
    }

    bool owner = true;
#if defined(_WIN32) && !defined(__CYGWIN__)
    // TODO: Needs error handling with name length > 256
    const char* cname = name.c_str();
    WCHAR tname[256] = {0,};

    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, cname, strlen(cname), tname, 256);
    HANDLE sem = CreateSemaphoreW(NULL,1,1,tname);
    if (sem == NULL) {
	owner = false;
	return new DIntGDL(0);
    }
#else
    sem_t *sem = sem_open(name.c_str(), O_CREAT | O_EXCL, 0666, 1);
    if (sem == SEM_FAILED)
    {  // semaphore exists. make another one, locked (value=0)
      owner = false;
      if (errno == EEXIST)
      {
        sem = sem_open(name.c_str(), O_CREAT ,0666, 0);
      }
      if (sem == SEM_FAILED)
      {
        return new DIntGDL(0);
      }
    }
#endif

    // Behavior for different values of DESTROY_SEMAPHORE:
    // DESTROY_SEMAPHORE | owner    | other (== !owner)
    // ------------------+----------+-----------
    // not set           | delete   | ignore
    // != 0              | delete   | delete
    // 0                 | ignore   | ignore
    sem_data_t data;
    data.sem = sem;

    sem_set_owner(data, owner);
    sem_set_deletable(data, (!destroyKWPresent && owner) || (destroy != 0));
    sem_set_locked(data, false);

    sem_add(name, data);

    return new DIntGDL(1);
  }
Esempio n. 2
0
  BaseGDL* sem_create(EnvT *e)
  {
    SizeT nParam = e->NParam(1); // 1 is the minimal number of parameter required

    DString name;
    e->AssureStringScalarPar(0, name); // IDL accepts null-string name

    int destroyIx = e->KeywordIx("DESTROY_SEMAPHORE");
    bool destroyKWPresent = e->KeywordPresent(destroyIx);
    DLong destroy = 0;
    if (destroyKWPresent) 
    {
      destroy = (*e->GetKWAs<DLongGDL>(0))[0];
    }

    bool owner = true;
#ifdef _MSC_VER
    HANDLE sem = CreateSemaphore(NULL,1,1,name.c_str());
    if (sem == NULL) {
	owner = false;
	return new DIntGDL(0);
    }
#else
    sem_t *sem = sem_open(name.c_str(), O_CREAT | O_EXCL, 0666, 1);
    if (sem == SEM_FAILED)
    {
      owner = false;
      if (errno == EEXIST)
      {
        sem = sem_open(name.c_str(), 0);
      }
      if (sem == SEM_FAILED)
      {
        return new DIntGDL(0);
      }
    }
#endif

    // Behavior for different values of DESTROY_SEMAPHORE:
    // DESTROY_SEMAPHORE | owner    | other (== !owner)
    // ------------------+----------+-----------
    // not set           | delete   | ignore
    // != 0              | delete   | delete
    // 0                 | ignore   | ignore
    sem_data_t data;
    data.sem = sem;

    sem_set_owner(data, owner);
    sem_set_deletable(data, (!destroyKWPresent && owner) || (destroy != 0));
    sem_set_locked(data, false);

    sem_add(name, data);

    return new DIntGDL(1);
  }