Exemple #1
0
/* ========================================================================= */
int shm_read(ShmLink *cont, void *dptr, unsigned int offset,
             unsigned int size)
{
  int res;

  if (cont == NULL) return -1;
  if (semtimedop(cont->sem_id, lock, 2, &timeout) < 0)
  {
    (void)snprintf(cont->err_msg, SHMCI_EMSG_SIZE,
                   "[%s:%d] Error locking semaphore. %s",
                   _FILE_, __LINE__, strerror(errno));
    return -3;
  }

  res = shm_read_generic(dptr, offset, size, cont);

  if (semctl(cont->sem_id, 0, SETVAL, 0) < 0)
  {
    (void)snprintf(cont->err_msg, SHMCI_EMSG_SIZE,
                   "[%s:%d] Error unlocking semaphore. %s",
                   _FILE_, __LINE__, strerror(errno));
    return -4;
  }
  if (res < 0) return -5; /* error description has been already written */
  else return 0;
}
Exemple #2
0
/* block when semid[index] is negative and ms has not timeout. */
int try_lock_sem(int semid, int index, int ms)
{
    int ret;
    struct sembuf op;
    op.sem_num= index;
    op.sem_op= -1;

    if(ms< 1){
        op.sem_flg= IPC_NOWAIT;
        ret= semop(semid, &op, 1);
        if(-1== ret){
            printf("try_lock_sem error: %s\n",strerror(errno));
        }
    }
    else
    {
        /* to avoid unwanted exited */
        op.sem_flg= SEM_UNDO;
        struct timespec timeout;
        timeout.tv_sec= ms/ 1000;
        timeout.tv_nsec= (ms% 1000L)* 1000000L;
        ret= semtimedop(semid, &op, 1, &timeout);
        if(-1== ret){
            printf("try_lock_sem error: %s\n",strerror(errno));
        }
    }

//    if(-1== ret){
//        if(errno== EAGAIN) return EAGAIN;
//    }
    return ret;
}
Exemple #3
0
void * PassLockCode::Get(nat32 timeout)
{
 if (timeout==0xFFFFFFFF)
 {
  sembuf op;
   op.sem_num = 0;
   op.sem_op = -1;
   op.sem_flg = 0;
  if (semop(id,&op,1)!=0) return null<void*>();
 }
 else
 {
  sembuf op;
   op.sem_num = 0;
   op.sem_op = -1;
   op.sem_flg = 0;

  timespec to;
   to.tv_sec = timeout/1000;
   to.tv_nsec = (timeout%1000)*1000000;

  if (semtimedop(id,&op,1,&to)!=0) return null<void*>();
 }
 
 void * ret = ptr;
 ptr = null<void*>();
 return ret;
}
Exemple #4
0
/* 如sem[index]为负且不超时,则阻塞,超时则返回EAGAIN,否则将信号量减1,返回0*/
int TryLockSemaphore(int semid, int index, int milliseconds)
{
   	int ret;
	struct sembuf operation;
	operation.sem_num = index;
	operation.sem_op = -1;
if(milliseconds<1)
{
	  operation.sem_flg = IPC_NOWAIT;
	  ret= semop (semid, &operation, 1);
}
else
{
	  operation.sem_flg = SEM_UNDO;
      struct timespec timeout;
      timeout.tv_sec = (milliseconds / 1000);
      timeout.tv_nsec = (milliseconds - timeout.tv_sec*1000L)*1000000L;
	  ret= semtimedop(semid, &operation, 1, &timeout);
}
    if(ret == -1)
    {
      if(errno == EAGAIN) return EAGAIN;
    }
	return (ret == -1)? WhenError("Wait(semop)", errno):ret;
}
Exemple #5
0
/**
 * Increase or decrease the value of a semaphore, or wait the it to become 0
 * 
 * @param   bus        Bus information
 * @param   semaphore  The index of the semaphore, `S`, `W`, `X` or `Q`
 * @param   delta      The adjustment to make to the semaphore's value, 0 to wait for it to become 0
 * @param   flags      `SEM_UNDO` if the action should be undone when the program exits
 * @param   timeout    The amount of time to wait before failing
 * @return             0 on success, -1 on error
 */
static int
semaphore_op_timed(const bus_t *bus, int semaphore, int delta, int flags, const struct timespec *timeout)
{
	struct sembuf op;
	op.sem_num = (unsigned short)semaphore;
	op.sem_op = (short)delta;
	op.sem_flg = (short)flags;
	return semtimedop(bus->sem_id, &op, (size_t)1, timeout);
}
XnStatus XnLinuxSysVNamedEvent::Wait(XnUInt32 nMilliseconds)
{
	XnStatus nRetVal = XN_STATUS_OK;

	struct timespec time = {0};
	if (nMilliseconds != XN_WAIT_INFINITE)
	{
		nRetVal = xnOSGetTimeout(&time, nMilliseconds);
		if (nRetVal != XN_STATUS_OK)
		{
			return XN_STATUS_OS_EVENT_WAIT_FAILED;
		}
	}

	struct sembuf op[2];

	// wait for it to be 1
	op[0].sem_num = XN_EVENT_SEM_SIGNALED;
	op[0].sem_op = -1;
	op[0].sem_flg = 0;

	// re set it (if manual reset)
	op[1].sem_num = XN_EVENT_SEM_SIGNALED;
	op[1].sem_op = 1;
	op[1].sem_flg = 0;

	XnInt32 nOpsCount = m_bManualReset ? 2 : 1;

	if (XN_WAIT_INFINITE != nMilliseconds)
	{
#if _GNU_SOURCE
		if (0 != semtimedop(m_hSem, op, nOpsCount, &time))
#else
		if (0 != semop(m_hSem, op, nOpsCount))	
#endif
		{
			if(EAGAIN == errno)
			{
				return XN_STATUS_OS_EVENT_TIMEOUT;
			}
			return XN_STATUS_OS_EVENT_WAIT_FAILED;
		}
	}
	else
	{
		if (0 != semop(m_hSem, op, nOpsCount))
		{
			return XN_STATUS_OS_EVENT_WAIT_FAILED;
		}
	}

	return (XN_STATUS_OK);
}
Exemple #7
0
long
lx_semtimedop(int semid, void *p1, size_t nsops, struct timespec *timeout)
{
	int r;
	struct sembuf *sops = (struct sembuf *)p1;

	lx_debug("\nsemtimedop(%d, 0x%p, %u, 0x%p)\n", semid, sops, nsops,
	    timeout);
	if (nsops == 0)
		return (-EINVAL);

	r = semtimedop(semid, sops, nsops, timeout);
	return ((r < 0) ? -errno : r);
}
Exemple #8
0
int ipc_wake_some(struct sem_wakeup_info *wi, int num_semids, int num)
{
	int i;
	int ret;
	struct lockinfo *l;
	int found = 0;

	for (i = 0; i < num_semids; i++) {
		wi[i].wakeup_count = 0;
	}
	while(num > 0) {
		struct sembuf *sb;
		l = worklist_rm();
		if (!l)
			break;
		if (l->data != 1)
			fprintf(stderr, "warning, lockinfo data was %d\n",
				l->data);
		l->data = 0;
		sb = wi[l->id].sb + wi[l->id].wakeup_count;
		sb->sem_num = l->index;
		sb->sem_op = 1;
		sb->sem_flg = IPC_NOWAIT;
		wi[l->id].wakeup_count++;
		found++;
		num--;
	}
	if (!found)
		return 0;
	for (i = 0; i < num_semids; i++) {
		int wakeup_total;
		int cur;
		int offset = 0;
		if (!wi[i].wakeup_count)
			continue;
		wakeup_total = wi[i].wakeup_count;
		while(wakeup_total > 0) {
			cur = wakeup_total > 64 ? 64 : wakeup_total;
			ret = semtimedop(semid_lookup[i], wi[i].sb + offset,
					 cur, NULL);
			if (ret) {
				perror("semtimedop");
				exit(1);
			}
			offset += cur;
			wakeup_total -= cur;
		}
	}
	return found;
}
void *thread_waiter()
{
	// when we wake up
	// refilling the rt_waiter
	thread_waiter_tid = syscall(__NR_gettid);
	int semid,i;
	struct sembuf sops[32];
	timeout.tv_sec = 0;
	timeout.tv_nsec = 0;
	// init sops struct
	for(i = 0; i < 32; i++) {
		sops[i].sem_num = 0x0;
		sops[i].sem_op = 0x0;
		sops[i].sem_flg = 0x0;
	}
	sops[27].sem_op = 0xffff; 
	sops[27].sem_flg = 0xffff;
	
	sops[28].sem_num = 0x4141; 
	sops[28].sem_op = 0x4141; 
	sops[28].sem_flg = 0x4444; 

	sops[29].sem_num = 0x3333;
	sops[29].sem_op = 0x0000;  
	sops[29].sem_flg = 0x4141;

	sops[30].sem_num = 0x0000; 
	sops[30].sem_op = 0x4141;  

	semid = semget(IPC_PRIVATE,200,IPC_CREAT | 0660);
	if (semid < 0) {
		printf("semget error\n");
		die();
	}
	setpriority(PRIO_PROCESS, 0, 12);
	printf("this is thread_waiter %d\n",thread_waiter_tid);
	// block on lock 1 , wait for lock2
	syscall(__NR_futex, &lock1, FUTEX_WAIT_REQUEUE_PI, 0, NULL, &lock2, 0);
	printf("thread waiter wake up....\n");
	/* refilling the rt_waiter */
	semtimedop(semid,sops,32,&timeout);
	die();
}
Exemple #10
0
bit GateLock::Queue(nat32 timeout)
{
 sembuf op;
  op.sem_num = 0;
  op.sem_op = 0;
  op.sem_flg = 0;

 if (timeout==0xFFFFFFFF)
 {
  return semop(id,&op,1)==0;
 }
 else
 {
  timespec to;
   to.tv_sec = timeout/1000;
   to.tv_nsec = (timeout%1000)*1000000;

  return semtimedop(id,&op,1,&to)==0;
 }
}
Exemple #11
0
//---------------------------------------------------------------
// svipc_semtake
//---------------------------------------------------------------
int svipc_semtake(key_t key, int id, int count, float wait)
{
  int sempoolid, status;

  Debug(5, "svipc_semtake %f\n", wait);

  struct timespec timeout, *pto = NULL;

  if (wait >= 0.0)
    {
      timeout.tv_sec = (time_t) wait;
      timeout.tv_nsec = (long int)((wait - timeout.tv_sec) * 1e9);
      pto = &timeout;
    }

  sempoolid = semget(key, 0, 0666);

  if (sempoolid == -1)
    {
      perror("sempoolid semget failed");
      return -1;
    }

  // take the semaphore
  struct sembuf sops;
  sops.sem_num = id;
  sops.sem_op = -count;	//
  sops.sem_flg = 0;	// fixme - undo if interrupted?

  status = semtimedop(sempoolid, &sops, 1, pto);

  if (status == -1)
    {
      if (errno != EAGAIN)
        { perror("semop failed"); }

      return -1;
    }

  return 0;
}
Exemple #12
0
/* ========================================================================= */
int shm_clean(ShmLink *cont)
{
  if (cont == NULL) return -1;
  if (semtimedop(cont->sem_id, lock, 2, &timeout) < 0)
  {
    (void)snprintf(cont->err_msg, SHMCI_EMSG_SIZE,
                   "[%s:%d] Error locking semaphore. %s",
                   _FILE_, __LINE__, strerror(errno));
    return -2;
  }

  memset(cont->ptr,0,cont->shm_size);

  if (semctl(cont->sem_id, 0, SETVAL, 0) < 0)
  {
    (void)snprintf(cont->err_msg, SHMCI_EMSG_SIZE,
                   "[%s:%d] Error unlocking semaphore. %s",
                   _FILE_, __LINE__, strerror(errno));
     return -3;
  }
  return 0;
}
Exemple #13
0
/**
 * Decrements the client's semaphor (to read the next available chunk)
 */
static int
decrement_client (xmmsc_vis_unixshm_t *t, unsigned int blocking) {
	/* alter semaphore 1 by -1, no flags */
	struct sembuf op = { 1, -1, 0 };
	struct timespec time;
	time.tv_sec = blocking / 1000;
	time.tv_nsec = (blocking % 1000) * 1000000;
	if (semtimedop (t->semid, &op, 1, &time) == -1) {
		switch (errno) {
		case EAGAIN:
		case EINTR:
			return 0;
		case EINVAL:
		case EIDRM:
			return -1;
		default:
			perror ("Unexpected semaphore problem");
			return -1;
		}
	}
	return 1;
}
static int absem_wait(void)
{
    int		absem;
    struct sembuf	sops;
    long		now;
    long		start_wait;
    struct timespec	timeout;

    if((absem = absem_get(0)) < 0) {
        perror(__FUNCTION__);
        return absem;
    }
    sops.sem_num = 0;
    sops.sem_op = -1;
    sops.sem_flg = 0;
    start_wait = time(NULL);
    timeout.tv_sec = timeout_seconds;
    timeout.tv_nsec = 0;
    if(semtimedop(absem, &sops, 1, &timeout) < 0) {
        switch(errno) {
        case EIDRM:	/* Removed -- OK */
            break;
        case EAGAIN:	/* Timeout -- Report */
            fprintf(stderr, "Astribanks waiting timed out\n");
            return -errno;
        default:	/* Unexpected errors */
            perror("semop");
            return -errno;
        }
        /* fall-thgough */
    }
    now = time(NULL);
    if(debug)
        fprintf(stderr, "%s: waited on absem %ld seconds\n", progname, now - start_wait);
    if(verbose)
        printf("Finished after %ld seconds\n", now - start_wait);
    return 0;
}
Exemple #15
0
bool CSem::TryWait(struct timespec *ts)
{
    struct sembuf sb;
    sb.sem_num = 0;
    sb.sem_op = -1;
    sb.sem_flg = SEM_UNDO | IPC_NOWAIT;

    /// no wait
    if (ts == NULL) {
        if (semop(m_semid, &sb, 1) == -1) {
            if (errno != EAGAIN) {
                fprintf(stderr, "semop wait error![%s:%d][%s]\n", __FILE__, __LINE__,strerror(errno));
            }
            return false;
        }
        return true;
    }

    ///wait time
    for (int i = 0;i < 5; i++) {
        if (semtimedop(m_semid, &sb, 1, ts) == -1) {
            if (errno != EAGAIN) {
                fprintf(stderr, "semtimedop wait error![%s:%d][%s]\n", __FILE__, __LINE__,strerror(errno));
                return false;
            } else if (errno == EINTR) {
                continue;
            } else {
                return false;
            }
        }
        else {
            return true;
        }
    }

    return false;
}
Exemple #16
0
/* ipc semaphore post& wait */
void wait_ipc_sem(struct lockinfo *l)
{
	struct sembuf sb;
	int ret;
	struct timespec *tvp = NULL;
	struct timespec tv = { 0, 1 };

	sb.sem_num = l->index;
	sb.sem_flg = 0;

	sb.sem_op = -1;
	l->data = 1;

	if (timeout_test && (l->id % 5) == 0)
		tvp = &tv;

	worklist_add(l);
	ret = semtimedop(semid_lookup[l->id], &sb, 1, tvp);

	while(l->data != 0 && tvp) {
		struct timespec tv2 = { 0, 500 };
		nanosleep(&tv2, NULL);
	}

	if (l->data != 0) {
		if (tvp)
			return;
		fprintf(stderr, "wakeup without data update\n");
		exit(1);
	}
	if (ret) {
		if (errno == EAGAIN && tvp)
			return;
		perror("semtimed op");
		exit(1);
	}
}
Exemple #17
0
bit EventLock::Get(nat32 timeout)
{
 if (timeout==0xFFFFFFFF)
 {
  sembuf op;
   op.sem_num = 0;
   op.sem_op = -1;
   op.sem_flg = 0;
  return semop(id,&op,1)==0;   
 }
 else
 {
  sembuf op;
   op.sem_num = 0;
   op.sem_op = -1;
   op.sem_flg = 0;

  timespec to;
   to.tv_sec = timeout/1000;
   to.tv_nsec = (timeout%1000)*1000000;

  return semtimedop(id,&op,1,&to)==0;
 }
}
Exemple #18
0
Fichier : sem.c Projet : khuey/rr
static int run_child(void) {
  int child2;
  int status;
  struct sembuf ops[2];
  struct timespec ts = { 0, 20000000 };
  struct timespec ts_short = { 0, 10000000 };
  struct timespec ts_long = { 10000, 0 };
  union semun un_arg;
  struct semid_ds* ds;
  struct seminfo* si;
  unsigned short* array;

  ops[0].sem_num = 0;
  ops[0].sem_op = 1;
  ops[0].sem_flg = SEM_UNDO;
  ops[1].sem_num = 1;
  ops[1].sem_op = 1;
  ops[1].sem_flg = SEM_UNDO;
  test_assert(0 == semop(semid, ops, 2));
  *shmem = 0;

  ALLOCATE_GUARD(ds, 'd');
  un_arg.buf = ds;
  test_assert(0 == semctl(semid, 0, IPC_STAT, un_arg));
  VERIFY_GUARD(ds);
  test_assert(ds->sem_perm.mode == 0666);
  test_assert(ds->sem_nsems == COUNT);

  ds->sem_perm.mode = 0660;
  test_assert(0 == semctl(semid, 0, IPC_SET, un_arg));

  ALLOCATE_GUARD(si, 'i');
  un_arg.__buf = si;
  /* The following syscall should always return >= 1, but
     sometimes it returns 0. I don't know why. */
  test_assert(0 <= semctl(semid, 0, IPC_INFO, un_arg));
  VERIFY_GUARD(si);
  test_assert(si->semvmx > 0);
  test_assert(si->semusz < 100000);

  /* The following syscall should always return >= 1, but
     sometimes it returns 0. I don't know why. */
  test_assert(0 <= semctl(semid, 0, SEM_INFO, un_arg));
  VERIFY_GUARD(si);
  test_assert(si->semusz > 0);
  test_assert(si->semusz < 100000);

  array = allocate_guard(COUNT * sizeof(*array), 'a');
  un_arg.array = array;
  test_assert(0 == semctl(semid, 0, GETALL, un_arg));
  verify_guard(COUNT * sizeof(*array), array);
  test_assert(array[0] == 1);
  test_assert(array[1] == 1);
  test_assert(array[2] == 0);
  test_assert(array[3] == 0);

  array[2] = 2;
  test_assert(0 == semctl(semid, 0, SETALL, un_arg));

  test_assert(0 == semctl(semid, 1, GETNCNT, NULL));

  test_assert(getpid() == semctl(semid, 1, GETPID, NULL));

  test_assert(2 == semctl(semid, 2, GETVAL, NULL));

  test_assert(0 == semctl(semid, 0, GETZCNT, NULL));

  un_arg.val = 0;
  test_assert(0 == semctl(semid, 2, SETVAL, un_arg));

  if ((child2 = fork()) == 0) {
    ops[0].sem_op = -1;
    ops[1].sem_op = -1;
    /* The semtimedop timeout is irrelevant. We're just checking that the
       syscall works. */
    test_assert(0 == semtimedop(semid, ops, 2, &ts_long));

    *shmem = 1;

    test_assert(0 == nanosleep(&ts, NULL));

    *shmem = 0;

    ops[0].sem_op = 1;
    ops[1].sem_op = 1;
    test_assert(0 == semtimedop(semid, ops, 2, &ts));

    return 0;
  }

  test_assert(0 == nanosleep(&ts_short, NULL));

  ops[0].sem_op = -1;
  ops[1].sem_op = -1;
  test_assert(0 == semop(semid, ops, 2));

  test_assert(*shmem == 0);

  ops[0].sem_op = 1;
  ops[1].sem_op = 1;
  test_assert(0 == semop(semid, ops, 2));

  test_assert(child2 == waitpid(child2, &status, __WALL));
  test_assert(0 == status);

  return 0;
}
int
main(void)
{
	static const int bogus_semid = 0xfdb97531;
	static void * const bogus_sops = (void *) -1L;
	static const size_t bogus_nsops = (size_t) 0xdefaceddeadbeefULL;

	TAIL_ALLOC_OBJECT_CONST_PTR(struct timespec, ts);
	int rc;

	id = semget(IPC_PRIVATE, 1, 0600);
	if (id < 0)
		perror_msg_and_skip("semget");
	atexit(cleanup);

	union semun sem_union = { .val = 0 };
	if (semctl(id, 0, SETVAL, sem_union) == -1)
		perror_msg_and_skip("semctl");

	TAIL_ALLOC_OBJECT_CONST_PTR(struct sembuf, sem_b);
	TAIL_ALLOC_OBJECT_CONST_PTR(struct sembuf, sem_b2);

	rc = semop(bogus_semid, NULL, bogus_nsops);
	printf("semop(%d, NULL, %u) = %s\n",
		bogus_semid, (unsigned) bogus_nsops, sprintrc(rc));

	rc = semop(bogus_semid, bogus_sops, 1);
	printf("semop(%d, %p, %u) = %s\n",
		bogus_semid, bogus_sops, 1, sprintrc(rc));

	sem_b->sem_num = 0;
	sem_b->sem_op = 1;
	sem_b->sem_flg = SEM_UNDO;

	sem_b2->sem_num = 0xface;
	sem_b2->sem_op = 0xf00d;
	sem_b2->sem_flg = 0xbeef;

	rc = semop(bogus_semid, sem_b2, 2);
	printf("semop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u) = %s\n",
		bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
		sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
		sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
		(short) (sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT)),
		sem_b2 + 1, 2, sprintrc(rc));

	if (semop(id, sem_b, 1))
		perror_msg_and_skip("semop, 1");
	printf("semop(%d, [{0, 1, SEM_UNDO}], 1) = 0\n", id);

	sem_b->sem_op = -1;
	if (semop(id, sem_b, 1))
		perror_msg_and_skip("semop, -1");
	printf("semop(%d, [{0, -1, SEM_UNDO}], 1) = 0\n", id);

	rc = semtimedop(bogus_semid, NULL, bogus_nsops, NULL);
	printf("semtimedop(%d, NULL, %u, NULL) = %s\n",
		bogus_semid, (unsigned) bogus_nsops, sprintrc(rc));

	rc = semtimedop(id, sem_b + 1, 1, ts + 1);
	printf("semtimedop(%d, %p, 1, %p) = %s\n",
		id, sem_b + 1, ts + 1, sprintrc(rc));

	ts->tv_sec = 1;
	ts->tv_nsec = 123456789;
	rc = semtimedop(bogus_semid, sem_b2, 2, ts);
	printf("semtimedop(%d, [{%hu, %hd, %s%s%#hx}, ... /* %p */], %u"
		", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
		bogus_semid, sem_b2->sem_num, sem_b2->sem_op,
		sem_b2->sem_flg & SEM_UNDO ? "SEM_UNDO|" : "",
		sem_b2->sem_flg & IPC_NOWAIT ? "IPC_NOWAIT|" : "",
		(short) (sem_b2->sem_flg & ~(SEM_UNDO | IPC_NOWAIT)),
		sem_b2 + 1, 2,
		(long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec),
		sprintrc(rc));

	sem_b->sem_op = 1;
	if (semtimedop(id, sem_b, 1, NULL))
		perror_msg_and_skip("semtimedop, 1");
	printf("semtimedop(%d, [{0, 1, SEM_UNDO}], 1, NULL) = 0\n", id);

	sem_b->sem_op = -1;
	if (semtimedop(id, sem_b, 1, ts))
		perror_msg_and_skip("semtimedop, -1");
	printf("semtimedop(%d, [{0, -1, SEM_UNDO}], 1"
	       ", {tv_sec=%lld, tv_nsec=%llu}) = 0\n", id,
	       (long long) ts->tv_sec, zero_extend_signed_to_ull(ts->tv_nsec));

	sem_b->sem_op = 1;
	ts->tv_sec = 0xdeadbeefU;
	ts->tv_nsec = 0xfacefeedU;
	rc = semtimedop(id, sem_b, 1, ts);
	printf("semtimedop(%d, [{0, 1, SEM_UNDO}], 1"
	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
	       id, (long long) ts->tv_sec,
	       zero_extend_signed_to_ull(ts->tv_nsec), sprintrc(rc));

	sem_b->sem_op = -1;
	ts->tv_sec = (time_t) 0xcafef00ddeadbeefLL;
	ts->tv_nsec = (long) 0xbadc0dedfacefeedLL;
	rc = semtimedop(id, sem_b, 1, ts);
	printf("semtimedop(%d, [{0, -1, SEM_UNDO}], 1"
	       ", {tv_sec=%lld, tv_nsec=%llu}) = %s\n",
	       id, (long long) ts->tv_sec,
	       zero_extend_signed_to_ull(ts->tv_nsec), sprintrc(rc));

	puts("+++ exited with 0 +++");
	return 0;
}
Exemple #20
0
XN_C_API XnStatus xnOSLockMutex(const XN_MUTEX_HANDLE MutexHandle, XnUInt32 nMilliseconds)
{
	// Local function variables
	XnStatus nRetVal = XN_STATUS_OK;
	int rc = 0;

	// Make sure the actual mutex handle isn't NULL
	XN_RET_IF_NULL(MutexHandle, XN_STATUS_OS_INVALID_MUTEX);

#ifndef XN_PLATFORM_LINUX_NO_SYSV
	struct sembuf op;
	// try to decrease it by 1 (if it's 0, we'll wait)
	op.sem_num = 0;
	op.sem_op = -1;
	op.sem_flg = SEM_UNDO;
#endif

	if (nMilliseconds == XN_WAIT_INFINITE)
	{
		// lock via the OS
		if (MutexHandle->bIsNamed)
		{
#ifndef XN_PLATFORM_LINUX_NO_SYSV
			if (0 != semop(MutexHandle->NamedSem, &op, 1))
			{
				rc = errno;
			}
#endif
		}
		else
		{
			rc = pthread_mutex_lock(&MutexHandle->ThreadMutex);
		}
	}
	else
	{
		struct timespec time;
		
		// lock via the OS
		if (MutexHandle->bIsNamed)
		{
#ifndef XN_PLATFORM_LINUX_NO_SYSV
			nRetVal = xnOSGetTimeout(&time, nMilliseconds);
			if (nRetVal != XN_STATUS_OK)
			{
				return XN_STATUS_OS_MUTEX_LOCK_FAILED;
			}

#ifndef XN_PLATFORM_HAS_NO_TIMED_OPS
			if (0 != semtimedop(MutexHandle->NamedSem, &op, 1, &time))
#else
			if (0 != semop(MutexHandle->NamedSem, &op, 1))
#endif
			{
				rc = errno;
			}
#endif
		}
		else
		{
			// calculate timeout absolute time. First we take current time
			nRetVal = xnOSGetAbsTimeout(&time, nMilliseconds);
			if (nRetVal != XN_STATUS_OK)
			{
				return XN_STATUS_OS_MUTEX_LOCK_FAILED;
			}
			
#ifndef XN_PLATFORM_HAS_NO_TIMED_OPS
			rc = pthread_mutex_timedlock(&MutexHandle->ThreadMutex, &time);
#else
			rc = pthread_mutex_lock(&MutexHandle->ThreadMutex);
#endif
		}
	}
	
	// check for failures
	if (rc == ETIMEDOUT)
	{
		return (XN_STATUS_OS_MUTEX_TIMEOUT);
	}
	else if (rc != 0)
	{
		return (XN_STATUS_OS_MUTEX_LOCK_FAILED);
	}
	
	// All is good...
	return (XN_STATUS_OK);
}
Exemple #21
0
void
initialize_semaphore_set(semian_resource_t* res, const char* id_str, long permissions, int tickets, double quota)
{

  res->key = generate_key(id_str);
  res->strkey = (char*)  malloc((2 /*for 0x*/+ sizeof(uint64_t) /*actual key*/+ 1 /*null*/) * sizeof(char));
  sprintf(res->strkey, "0x%08x", (unsigned int) res->key);
  res->sem_id = semget(res->key, SI_NUM_SEMAPHORES, IPC_CREAT | IPC_EXCL | permissions);

  /*
  This approach is based on http://man7.org/tlpi/code/online/dist/svsem/svsem_good_init.c.html
  which avoids race conditions when initializing semaphore sets.
  */
  if (res->sem_id != -1) {
    // Happy path - we are the first worker, initialize the semaphore set.
    initialize_new_semaphore_values(res->sem_id, permissions);
  } else {
    // Something went wrong
    if (errno != EEXIST) {
      raise_semian_syscall_error("semget() failed to initialize semaphore values", errno);
    } else {
      // The semaphore set already exists, ensure it is initialized
      res->sem_id = wait_for_new_semaphore_set(res->key, permissions);
    }
  }

  set_semaphore_permissions(res->sem_id, permissions);

  /*
    Ensure that a worker for this process is registered.
    Note that from ruby we ensure that at most one worker may be registered per process.
  */
  if (perform_semop(res->sem_id, SI_SEM_REGISTERED_WORKERS, 1, SEM_UNDO, NULL) == -1) {
    rb_raise(eInternal, "error incrementing registered workers, errno: %d (%s)", errno, strerror(errno));
  }

  int state = 0;
  sem_meta_lock(res->sem_id); // Sets otime for the first time by acquiring the sem lock

  configure_tickets_args_t configure_tickets_args = (configure_tickets_args_t){
    .sem_id = res->sem_id,
    .tickets = tickets,
    .quota = quota,
  };
  rb_protect(
    configure_tickets,
    (VALUE)&configure_tickets_args,
    &state);

  sem_meta_unlock(res->sem_id);
  if (state) {
    rb_jump_tag(state);
  }
}

void
set_semaphore_permissions(int sem_id, long permissions)
{
  union semun sem_opts;
  struct semid_ds stat_buf;

  sem_opts.buf = &stat_buf;
  semctl(sem_id, 0, IPC_STAT, sem_opts);
  if ((stat_buf.sem_perm.mode & 0xfff) != permissions) {
    stat_buf.sem_perm.mode &= ~0xfff;
    stat_buf.sem_perm.mode |= permissions;
    semctl(sem_id, 0, IPC_SET, sem_opts);
  }
}

int
perform_semop(int sem_id, short index, short op, short flags, struct timespec *ts)
{
  struct sembuf buf = { 0 };

  buf.sem_num = index;
  buf.sem_op  = op;
  buf.sem_flg = flags;

  if (ts) {
    return semtimedop(sem_id, &buf, 1, ts);
  } else {
    return semop(sem_id, &buf, 1);
  }
}

int
get_sem_val(int sem_id, int sem_index)
{
  int ret = semctl(sem_id, sem_index, GETVAL);
  if (ret == -1) {
    rb_raise(eInternal, "error getting value of %s for sem %d, errno: %d (%s)", SEMINDEX_STRING[sem_index], sem_id, errno, strerror(errno));
  }
  return ret;
}
Exemple #22
0
  memset(&ds, 0, sizeof(ds));
  ASSERT_EQ(0, semctl(id, 0, IPC_STAT, &ds));
  ASSERT_EQ(1U, ds.sem_nsems);

  ASSERT_EQ(0, semctl(id, 0, GETVAL));

  // Increment.
  sembuf ops[] = {{ .sem_num = 0, .sem_op = 1, .sem_flg = 0 }};
  ASSERT_EQ(0, semop(id, ops, 1));
  ASSERT_EQ(1, semctl(id, 0, GETVAL));

  // Test timeouts.
  timespec ts = { .tv_sec = 0, .tv_nsec = 100 };
  ops[0] = { .sem_num = 0, .sem_op = 0, .sem_flg = 0 };
  errno = 0;
  ASSERT_EQ(-1, semtimedop(id, ops, 1, &ts));
  ASSERT_EQ(EAGAIN, errno);
  ASSERT_EQ(1, semctl(id, 0, GETVAL));

  // Decrement.
  ops[0] = { .sem_num = 0, .sem_op = -1, .sem_flg = 0 };
  ASSERT_EQ(0, semop(id, ops, 1));
  ASSERT_EQ(0, semctl(id, 0, GETVAL));

  // Destroy the semaphore.
  ASSERT_EQ(0, semctl(id, 0, IPC_RMID));
}

TEST(sys_sem, semget_failure) {
  errno = 0;
  ASSERT_EQ(-1, semget(-1, -1, 0));
Exemple #23
0
int main(int argc, char **argv)
{
   int semid;
   struct sembuf sop;
#ifdef HAVE_SEMTIMEDOP
   struct timespec ts;
#endif
   
   if ((semid = semget(IPC_PRIVATE, 1, 0600)) < 0)
   {
      perror("semget");
      exit(1);
   }

   sop.sem_num = 0;
   sop.sem_op = 1;
   sop.sem_flg = 0;
   
   if (semop(semid, &sop, 1) < 0)
   {
      perror("semop");
      semctl(semid, 0, IPC_RMID);
      exit(1);
   }

   if (semctl(semid, 0, GETVAL) != 1)
   {
      perror("semctl GETVAL");
      semctl(semid, 0, IPC_RMID);
      exit(1);
   }

   if (semctl(semid, 0, GETPID) != getpid())
   {
      perror("semctl GETPID");
      semctl(semid, 0, IPC_RMID);
      exit(1);
   }

   /* The next call to semtimedop causes the program to hang on
      ppc32-linux (Yellow Dog 4.0).  I don't know why.  Hence the
      extended ifdef. */
#if defined(HAVE_SEMTIMEDOP) && !defined(__powerpc__)
   sop.sem_num = 0;
   sop.sem_op = 0;
   sop.sem_flg = 0;

   ts.tv_sec = 0;
   ts.tv_nsec = 1000000;
   
   if (semtimedop(semid, &sop, 1, &ts) < 0 && errno != EAGAIN)
   {
      perror("semtimedop");
      semctl(semid, 0, IPC_RMID);
      exit(1);
   }
#endif

   sop.sem_num = 0;
   sop.sem_op = -1;
   sop.sem_flg = 0;
   
   if (semop(semid, &sop, 1) < 0)
   {
      perror("semop");
      semctl(semid, 0, IPC_RMID);
      exit(1);
   }

#ifdef HAVE_SEMTIMEDOP
   sop.sem_num = 0;
   sop.sem_op = 0;
   sop.sem_flg = 0;

   ts.tv_sec = 0;
   ts.tv_nsec = 1000;
   
   if (semtimedop(semid, &sop, 1, &ts) < 0)
   {
      perror("semtimedop");
      semctl(semid, 0, IPC_RMID);
      exit(1);
   }
#endif

   if (semctl(semid, 0, IPC_RMID) < 0)
   {
      perror("semctl(IPC_RMID)");
      exit(1);
   }
         
   exit(0);
}
Exemple #24
0
XN_C_API XnStatus xnOSLockMutex(const XN_MUTEX_HANDLE MutexHandle, XnUInt32 nMilliseconds)
{
	// Local function variables
	XnStatus nRetVal = XN_STATUS_OK;
	int rc = 0;

	// Make sure the actual mutex handle isn't NULL
	XN_RET_IF_NULL(MutexHandle, XN_STATUS_OS_INVALID_MUTEX);

	struct sembuf op;
	// try to decrease it by 1 (if it's 0, we'll wait)
	op.sem_num = 0;
	op.sem_op = -1;
	op.sem_flg = SEM_UNDO;

	if (nMilliseconds == XN_WAIT_INFINITE)
	{
		// lock via the OS
		if (MutexHandle->bIsNamed)
		{
			if (0 != semop(MutexHandle->NamedSem, &op, 1))
			{
				rc = errno;
			}
		}
		else
		{
			rc = pthread_mutex_lock(&MutexHandle->ThreadMutex);
		}
	}
	else
	{
		// calculate timeout absolute time. First we take current time
		struct timespec time;
		time.tv_sec = (nMilliseconds / 1000);
		time.tv_nsec = ((nMilliseconds % 1000) * 1000000);
		
		// lock via the OS
		if (MutexHandle->bIsNamed)
		{
			if (0 != semtimedop(MutexHandle->NamedSem, &op, 1, &time))
			{
				rc = errno;
			}
		}
		else
		{
			rc = pthread_mutex_timedlock(&MutexHandle->ThreadMutex, &time);
		}
	}
	
	// check for failures
	if (rc == ETIMEDOUT)
	{
		return (XN_STATUS_OS_MUTEX_TIMEOUT);
	}
	else if (rc != 0)
	{
		return (XN_STATUS_OS_MUTEX_LOCK_FAILED);
	}
	
	// All is good...
	return (XN_STATUS_OK);
}
int main(void)
{
	key_t key;
	int sem;
	semun_t arg;
	int ret;
	struct sembuf semwait, semsignal;
	struct timespec timeout;

	/*
	 * This is not meant to be functionally
	 * correct, it is just used to check we
	 * can build minimal POSIX semaphore
	 * based code
	 */
	key = (key_t)getpid();
	sem = semget(key, 1, IPC_CREAT | S_IRUSR | S_IWUSR);
	arg.val = 1;
	ret = semctl(sem, 0, SETVAL, arg);
	(void)ret;
	semwait.sem_num = 0;
	semwait.sem_op = -1;
	semwait.sem_flg = SEM_UNDO;
	(void)semwait;
	(void)clock_gettime(CLOCK_REALTIME, &timeout);
	timeout.tv_sec++;
#if defined(__linux__)
	ret = semtimedop(sem, &semwait, 1, &timeout);
	(void)ret;
#endif

	semsignal.sem_num = 0;
	semsignal.sem_op = 1;
	semsignal.sem_flg = SEM_UNDO;

	ret = semop(sem, &semsignal, 1);
	(void)ret;

#if defined(IPC_STAT)
	{
		struct semid_ds ds;
		semun_t s;

		s.buf = &ds;
		ret = semctl(sem, 0, IPC_STAT, &s);
		(void)ret;
	}
#endif
#if defined(SEM_STAT)
	{
		struct semid_ds ds;
		semun_t s;

		s.buf = &ds;
		ret = semctl(sem, 0, SEM_STAT, &s);
		(void)ret;
	}
#endif
#if defined(IPC_INFO) && defined(__linux__)
	{
		struct seminfo si;
		semun_t s;

		s.__buf = &si;
		ret = semctl(sem, 0, IPC_INFO, &s);
		(void)ret;
	}
#endif
#if defined(SEM_INFO) && defined(__linux__)
	{
		struct seminfo si;
		semun_t s;

		s.__buf = &si;
		ret = semctl(sem, 0, SEM_INFO, &s);
		(void)ret;
	}
#endif
#if defined(GETVAL)
	ret = semctl(sem, 0, GETVAL);
	(void)ret;
#endif
#if defined(GETPID)
	ret = semctl(sem, 0, GETPID);
	(void)ret;
#endif
#if defined(GETNCNT)
	ret = semctl(sem, 0, GETNCNT);
	(void)ret;
#endif
#if defined(GEZCNT)
	ret = semctl(sem, 0, GETZCNT);
	(void)ret;
#endif
	ret = semctl(sem, 0, IPC_RMID);
	(void)ret;

	return 0;
}