Beispiel #1
0
int pthread_mutex_unlock(pthread_mutex_t *m)
{
    int r = mutex_ref_unlock(m);
    if(r) return r;

    mutex_t *_m = (mutex_t *)*m;
    if (_m->type == PTHREAD_MUTEX_NORMAL)
    {
        if (!COND_LOCKED(_m))
            return mutex_unref(m,EPERM);
    }
    else if (!COND_LOCKED(_m) || !COND_OWNER(_m))
        return mutex_unref(m,EPERM);
    if (_m->type == PTHREAD_MUTEX_RECURSIVE)
    {
        if(InterlockedDecrement(&_m->count))
            return mutex_unref(m,0);
    }
#if defined USE_MUTEX_Mutex
    UNSET_OWNER(_m);
    if (_m->h != NULL && !ReleaseSemaphore(_m->h, 1, NULL)) {
        SET_OWNER(_m);
        /* restore our own bookkeeping */
        return mutex_unref(m,EPERM);
    }
#else /* USE_MUTEX_CriticalSection */
    UNSET_OWNER(_m);
    LeaveCriticalSection(&_m->cs.cs);
#endif
    return mutex_unref(m,0);
}
Beispiel #2
0
static __attribute__((noinline)) int
_mutex_trylock(pthread_mutex_t *m)
{
    int r = 0;
    mutex_t *_m = (mutex_t *)*m;
    if (_m->type != PTHREAD_MUTEX_NORMAL)
    {
        if (COND_LOCKED(_m))
        {
            if (_m->type == PTHREAD_MUTEX_RECURSIVE && COND_OWNER(_m))
            {
                InterlockedIncrement(&_m->count);
                return 0;
            }
            return EBUSY;
        }
    } else if (COND_LOCKED(_m))
        return EBUSY;
#if defined USE_MUTEX_Mutex
    r = do_sema_b_wait_intern (_m->h, 1, 0);
    if (r == ETIMEDOUT) r = EBUSY;
#else /* USE_MUTEX_CriticalSection */
    r = TryEnterCriticalSection(&_m->cs.cs) ? 0 : EBUSY;
#endif
    if (!r)
    {
        _m->count = 1;
        SET_OWNER(_m);
    }
    return r;
}
Beispiel #3
0
mono_handle_new_interior (gpointer rawptr, const char *owner)
#endif
{
	MonoThreadInfo *info = mono_thread_info_current ();
	HandleStack *handles = (HandleStack *)info->handle_stack;
	HandleChunk *top = handles->interior;
#ifdef MONO_HANDLE_TRACK_SP
	mono_handle_chunk_leak_check (handles);
#endif

	g_assert (top);

	/*
	 * Don't extend the chunk now, interior handles are
	 * only used for icall arguments, they shouldn't
	 * overflow.
	 */
	g_assert (top->size < OBJECTS_PER_HANDLES_CHUNK);
	int idx = top->size;
	gpointer *objslot = &top->elems [idx].o;
	*objslot = NULL;
	mono_memory_write_barrier ();
	top->size++;
	mono_memory_write_barrier ();
	*objslot = rawptr;
	SET_OWNER (top,idx);
	SET_SP (handles, top, idx);
	return objslot;
}
Beispiel #4
0
static WINPTHREADS_ATTRIBUTE((noinline)) int
_mutex_trylock(pthread_mutex_t *m)
{
  int r = 0;
  mutex_t *_m = (mutex_t *)*m;
  
  if (_m->type != PTHREAD_MUTEX_NORMAL)
  {
    if (COND_LOCKED(_m))
    {
      if (_m->type == PTHREAD_MUTEX_RECURSIVE && COND_OWNER(_m))
	  {
	    InterlockedIncrement(&_m->count);
	    return 0;
	  }
	
	  return EBUSY;
    }
  } else if (COND_LOCKED(_m))
    return EBUSY;
    
  r = do_sema_b_wait_intern (_m->h, 1, 0);
  
  if (r == ETIMEDOUT) 
    r = EBUSY;
  else if (!r)
  {
    _m->count = 1;
    SET_OWNER(_m);
  }
  
  return r;
}
Beispiel #5
0
int pthread_mutex_unlock(pthread_mutex_t *m)
{    
  mutex_t *_m;
  int r = mutex_ref_unlock(m);
  
  if(r) {
#if 0
    printf("thread %d, la pool, no user unset in mutex %p\n", GetCurrentThreadId(), m);
#endif
    return r;
  }

  _m = (mutex_t *)*m;
  
  if (_m->type == PTHREAD_MUTEX_NORMAL)
  {
    if (!COND_LOCKED(_m))
      {
#if 0
	  printf("thread %d, mutex %p never locked, actually :p\n", GetCurrentThreadId(), m);
#endif
	  return mutex_unref(m, EPERM);
      }
  }
  else if (!COND_LOCKED(_m) || !COND_OWNER(_m)) {
#if 0
    printf("thread %d, mutex %p never locked or not owner, actually :p\n", GetCurrentThreadId(), m);
#endif
    return mutex_unref(m,EPERM);
  }
  
  if (_m->type == PTHREAD_MUTEX_RECURSIVE)
  {
    if(InterlockedDecrement(&_m->count)) {
#if 0
	  printf("thread %d, mutex %p decreasing recursive\n", GetCurrentThreadId(), m);
#endif
	  return mutex_unref(m,0);
	}
  }
#if 0
  printf("thread %d,unsetting owner of mutex %p\n", GetCurrentThreadId(), m);
#endif
  UNSET_OWNER(_m);
  
  if (_m->h != NULL && !ReleaseSemaphore(_m->h, 1, NULL)) {
  	SET_OWNER(_m);
#if 0
	printf("Error, not released! thread %d, setting owner of mutex m\n", GetCurrentThreadId(), m);
#endif
    /* restore our own bookkeeping */
    return mutex_unref(m,EPERM);
  }
  
  return mutex_unref(m,0);
}
Beispiel #6
0
mono_handle_new (MonoObject *obj, MonoThreadInfo *info, const char *owner)
#endif
{
	info = info ? info : mono_thread_info_current ();
	HandleStack *handles = info->handle_stack;
	HandleChunk *top = handles->top;
#ifdef MONO_HANDLE_TRACK_SP
	mono_handle_chunk_leak_check (handles);
#endif

retry:
	if (G_LIKELY (top->size < OBJECTS_PER_HANDLES_CHUNK)) {
		int idx = top->size;
		gpointer* objslot = &top->elems [idx].o;
		/* can be interrupted anywhere here, so:
		 * 1. make sure the new slot is null
		 * 2. make the new slot scannable (increment size)
		 * 3. put a valid object in there
		 *
		 * (have to do 1 then 3 so that if we're interrupted
		 * between 1 and 2, the object is still live)
		 */
		*objslot = NULL;
		SET_OWNER (top,idx);
		SET_SP (handles, top, idx);
		mono_memory_write_barrier ();
		top->size++;
		mono_memory_write_barrier ();
		*objslot = obj;
		return objslot;
	}
	if (G_LIKELY (top->next)) {
		top->next->size = 0;
		/* make sure size == 0 is visible to a GC thread before it sees the new top */
		mono_memory_write_barrier ();
		top = top->next;
		handles->top = top;
		goto retry;
	}
	HandleChunk *new_chunk = new_handle_chunk ();
	new_chunk->size = 0;
	new_chunk->prev = top;
	new_chunk->next = NULL;
	/* make sure size == 0 before new chunk is visible */
	mono_memory_write_barrier ();
	top->next = new_chunk;
	handles->top = new_chunk;
	goto retry;
}
Beispiel #7
0
static int pthread_mutex_lock_intern(pthread_mutex_t *m, DWORD timeout)
{
    mutex_t *_m;
    int r;
    r = mutex_ref(m);
    if(r) return r;

    _m = (mutex_t *)*m;
    if (_m->type != PTHREAD_MUTEX_NORMAL)
    {
        if (COND_LOCKED(_m))
        {
            if (COND_OWNER(_m))
            {
                if (_m->type == PTHREAD_MUTEX_RECURSIVE)
                {
                    InterlockedIncrement(&_m->count);
                    return mutex_unref(m,0);
                }
                return mutex_unref(m, EDEADLK);
            }
        }
    } else {
#if !defined USE_MUTEX_Mutex
        if (COND_OWNER(_m))
        {
            do {
                Sleep(0); /* waiter that owner gets released.  */
            } while (COND_OWNER(_m));
        }
#endif
    }
#if defined USE_MUTEX_Mutex
    r = do_sema_b_wait_intern (_m->h, 1, timeout);
#else /* USE_MUTEX_CriticalSection */
    EnterCriticalSection(&_m->cs.cs);
    r = 0;
#endif
    if (r == 0)
    {
        _m->count = 1;
        SET_OWNER(_m);
    }
    return mutex_unref(m,r);

}
Beispiel #8
0
static int
pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD timeout)
{
  mutex_t *_m;
  int r;
  HANDLE h;

  r = mutex_ref (m);
  if (r)
    return r;

  _m = (mutex_t *) *m;
  if (_m->type != PTHREAD_MUTEX_NORMAL)
  {
    if (COND_LOCKED(_m))
    {
      if (COND_OWNER(_m))
      {
	    if (_m->type == PTHREAD_MUTEX_RECURSIVE)
	    {
	      InterlockedIncrement(&_m->count);
	      return mutex_unref(m,0);
	    }

	    return mutex_unref(m, EDEADLK);
      }
    }
  }
  
  h = _m->h;
  mutex_unref (m, 0);

  r = do_sema_b_wait_intern (h, 1, timeout);

  if (r != 0)
    return r;

  r = mutex_ref (m);
  if (r)
    return r;

  _m->count = 1;
  SET_OWNER(_m);

  return mutex_unref (m, r);
}
Beispiel #9
0
mono_handle_new (MonoObject *object, const char *owner)
#endif
{
	MonoThreadInfo *info = mono_thread_info_current ();
	HandleStack *handles = (HandleStack *)info->handle_stack;
	HandleChunk *top = handles->top;

retry:
	if (G_LIKELY (top->size < OBJECTS_PER_HANDLES_CHUNK)) {
		int idx = top->size;
		MonoObject** objslot = chunk_element_objslot (top, idx);
		/* can be interrupted anywhere here, so:
		 * 1. make sure the new slot is null
		 * 2. make the new slot scannable (increment size)
		 * 3. put a valid object in there
		 *
		 * (have to do 1 then 3 so that if we're interrupted
		 * between 1 and 2, the object is still live)
		 */
		*objslot = NULL;
		mono_memory_write_barrier ();
		top->size++;
		mono_memory_write_barrier ();
		*objslot = object;
		SET_OWNER (top,idx);
		return objslot;
	}
	if (G_LIKELY (top->next)) {
		top->next->size = 0;
		/* make sure size == 0 is visible to a GC thread before it sees the new top */
		mono_memory_write_barrier ();
		top = top->next;
		handles->top = top;
		goto retry;
	}
	HandleChunk *new_chunk = g_new (HandleChunk, 1);
	new_chunk->size = 0;
	new_chunk->prev = top;
	new_chunk->next = NULL;
	/* make sure size == 0 before new chunk is visible */
	mono_memory_write_barrier ();
	top->next = new_chunk;
	handles->top = new_chunk;
	goto retry;
}
Beispiel #10
0
int pthread_mutex_unlock(pthread_mutex_t *m)
{    
  mutex_t *_m;
  int r = mutex_ref_unlock(m);
  
  if(r) {
    return r;
  }

  _m = (mutex_t *)*m;

  if (_m->type == PTHREAD_MUTEX_NORMAL)
  {
    if (!COND_LOCKED(_m))
      {
		  return mutex_unref(m, EPERM);
      }
  }
  else if (!COND_LOCKED(_m) || !COND_OWNER(_m)) {
    return mutex_unref(m,EPERM);
  }
  
  if (_m->type == PTHREAD_MUTEX_RECURSIVE)
  {
    if(InterlockedDecrement(&_m->count)) {
	  return mutex_unref(m,0);
	}
  }
  UNSET_OWNER(_m);

  if (_m->h != NULL && !ReleaseSemaphore(_m->h, 1, NULL)) {
  	SET_OWNER(_m);
    /* restore our own bookkeeping */
    return mutex_unref(m,EPERM);
  }

  return mutex_unref(m,0);
}
Beispiel #11
0
int __server_bind_port(int port)
{
    loop_t *loop = NULL;
    listener_t *listener = NULL;
#if 0    
    loop_t *loop = __get_main_loop(); //@{get_best_loop}
#else
    sched_t* sched = __get_main_sched();
    if (!sched)
    {
        goto _error;
    }

    loop = get_best_loop2(sched);
    if (!loop)
    {//@{not need free loop, because loop is own to sched}
        goto _error;
    }
    LOG_I("get best loop:%p", loop);
#endif
    
    listener = listener_new(port, NULL);
    if (!listener)
    {
        goto _error;
    }
    
    SET_OWNER(listener, (void*)loop);       // set listen's loop
    LOOP_ADD_WEIGHT(loop);

    listener->stat = STAT_ACCEPT;
    
    if(gettid() == loop->set_tid) 
    {
        fd_set_add_node3(loop->_set, (fd_node_t *)listener, FD_R_FLAGS, listener->timeout);
    }
    else
    {

#ifdef WIN32
        EnterCriticalSection(&loop->set_mutex);
#else
		pthread_mutex_lock(&loop->set_mutex);
#endif
        
        fd_set_add_node3(loop->_set, (fd_node_t *)listener, FD_R_FLAGS, listener->timeout);
#ifdef WIN32
		LeaveCriticalSection(&loop->set_mutex);	
#else
        pthread_mutex_unlock(&loop->set_mutex);
#endif
    }
    
    return 0;
    
_error:
    if (sched)
    {   printf("sched:%p g_sched: %p\n", sched, __get_main_sched());
        sched_del(sched);
        printf("g_sched: %p\n", __get_main_sched());
    }
    
    if(listener)
    {
        listener_del(listener);
    }
 
    return -1;
}
Beispiel #12
0
static int
pthread_mutex_lock_intern (pthread_mutex_t *m, DWORD timeout)
{
  mutex_t *_m;
  int r;
  HANDLE h;
#if 0
  int waited = 0;
#endif

  r = mutex_ref (m);
  if (r)
    return r;

  _m = (mutex_t *) *m;
  if (_m->type != PTHREAD_MUTEX_NORMAL)
  {
    if (COND_LOCKED(_m))
    {
      if (COND_OWNER(_m))
      {
	    if (_m->type == PTHREAD_MUTEX_RECURSIVE)
	    {
#if 0
	      printf("thread %d, recursive increment %p\n", GetCurrentThreadId(), m);
#endif
	  
	      InterlockedIncrement(&_m->count);
	      return mutex_unref(m,0);
	    }
#if 0
		printf("thread %d, non recursive increment?!? %p\n", GetCurrentThreadId(), m);
#endif
	    return mutex_unref(m, EDEADLK);
      }
    }
  }
  
  h = _m->h;
  mutex_unref (m, 0);

  if(_m->owner) {
#if 0
    waited = 1;
    printf("thread %d, waiting for thread: %d on mutex %p for %d time\n", GetCurrentThreadId(), _m->owner, m, timeout);
#endif
  }
  r = do_sema_b_wait_intern (h, 1, timeout);

#if 0
  if(waited) {
    printf("thread %d, resumed\n", GetCurrentThreadId());
  }
 #endif
 
  if (r != 0)
    return r;

  r = mutex_ref (m);
  if (r)
    return r;

  _m->count = 1;
  SET_OWNER(_m);
#if 0
  printf("thread %d, setting owner of mutex %p\n", GetCurrentThreadId(), m);
#endif
  return mutex_unref (m, r);
}