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); }
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); }