コード例 #1
0
ファイル: gwthread-pthread.c プロジェクト: Phonebooth/kannel
long gwthread_create_real(gwthread_func_t *func, const char *name, void *arg)
{
    int sigtrick = 0;
    sigset_t old_signal_set;
    long thread_id;

    /*
     * We want to make sure that only the main thread handles signals,
     * so that each signal is handled exactly once.  To do this, we
     * make sure that each new thread has all the signals that we
     * handle blocked.  To avoid race conditions, we block them in 
     * the spawning thread first, then create the new thread (which
     * inherits the settings), and then restore the old settings in
     * the spawning thread.  This means that there is a brief period
     * when no signals will be processed, but during that time they
     * should be queued by the operating system.
     */
    if (gwthread_self() == MAIN_THREAD_ID)
	    sigtrick = block_user_signals(&old_signal_set) == 0;

    thread_id = spawn_thread(func, name, arg);

    /*
     * Restore the old signal mask.  The new thread will have
     * inherited the resticted one, but the main thread needs
     * the old one back.
     */
    if (sigtrick)
 	    restore_user_signals(&old_signal_set);
    
    return thread_id;
}
コード例 #2
0
ファイル: list.c プロジェクト: LeeVidor/kannel-mongodb
void *gwlist_timed_consume(List *list, long sec)
{
    void *item;
    struct timespec abstime;
    int rc;

    abstime.tv_sec = time(NULL) + sec;
    abstime.tv_nsec = 0;

    lock(list);
    ++list->num_consumers;
    while (list->len == 0 && list->num_producers > 0) {
        list->single_operation_lock->owner = -1;
        rc = pthread_cond_timedwait(&list->nonempty,
                          &list->single_operation_lock->mutex, &abstime);
        list->single_operation_lock->owner = gwthread_self();
        if (rc == ETIMEDOUT)
            break;
    }
    if (list->len > 0) {
        item = GET(list, 0);
        delete_items_from_list(list, 0, 1);
    } else {
        item = NULL;
    }
    --list->num_consumers;
    unlock(list);
    return item;
}
コード例 #3
0
ファイル: conn.c プロジェクト: pwhelan/kannel
/* Lock a Connection's write direction, if the Connection is unclaimed */
static void inline lock_out(Connection *conn)
{
    gw_assert(conn != NULL);

    if (conn->claimed)
        gw_assert(gwthread_self() == conn->claiming_thread);
    else
        mutex_lock(conn->outlock);
}
コード例 #4
0
ファイル: gwthread-pthread.c プロジェクト: Phonebooth/kannel
void gwthread_wakeup_all(void)
{
    long i;
    long our_thread = gwthread_self();

    for (i = 0; i < THREADTABLE_SIZE; ++i) {
        if (THREAD(our_thread) != THREAD(i))
            gwthread_wakeup(i);
    }
}
コード例 #5
0
ファイル: conn.c プロジェクト: pwhelan/kannel
void conn_claim(Connection *conn)
{
    gw_assert(conn != NULL);

    if (conn->claimed)
        panic(0, "Connection is being claimed twice!");
    conn->claimed = 1;
#ifndef NO_GWASSERT
    conn->claiming_thread = gwthread_self();
#endif
}
コード例 #6
0
ファイル: gwthread-pthread.c プロジェクト: Phonebooth/kannel
static void *new_thread(void *arg)
{
    int ret;
    struct new_thread_args *p = arg;

    /* Make sure we don't start until our parent has entered
     * our thread info in the thread table. */
    lock();
    /* check for initialization errors */
    if (p->failed) {
        /* Must free p before signaling our exit, otherwise there is
        * a race with gw_check_leaks at shutdown. */
        gw_free(p);
        delete_threadinfo();
        unlock();
        return NULL;
    }
    unlock();

    /* This has to be done here, because pthread_setspecific cannot
     * be called by our parent on our behalf.  That's why the ti
     * pointer is passed in the new_thread_args structure. */
    /* Synchronization is not a problem, because the only thread
     * that relies on this call having been made is this one --
     * no other thread can access our TSD anyway. */
    ret = pthread_setspecific(tsd_key, p->ti);
    if (ret != 0) {
        panic(ret, "gwthread-pthread: pthread_setspecific failed");
    }

    p->ti->pid = getpid();
    debug("gwlib.gwthread", 0, "Thread %ld (%s) maps to pid %ld.",
          p->ti->number, p->ti->name, (long) p->ti->pid);

    (p->func)(p->arg);

    lock();
    debug("gwlib.gwthread", 0, "Thread %ld (%s) terminates.",
          p->ti->number, p->ti->name);
    alert_joiners();
#ifdef HAVE_LIBSSL
    /* Clear the OpenSSL thread-specific error queue to avoid
     * memory leaks. */
    ERR_remove_state(gwthread_self());
#endif /* HAVE_LIBSSL */
    /* Must free p before signaling our exit, otherwise there is
     * a race with gw_check_leaks at shutdown. */
    gw_free(p);
    delete_threadinfo();
    unlock();

    return NULL;
}
コード例 #7
0
ファイル: check_list.c プロジェクト: frese/mbuni
static void producer(void *arg) {
	long i, index;
	long id;
	struct producer_info *info;

	info = arg;

	id = gwthread_self();
	index = info->start_index;
	for (i = 0; i < NUM_ITEMS_PER_PRODUCER; ++i, ++index)
		gwlist_produce(info->list, new_item(id, i, index));
	gwlist_remove_producer(info->list);
}
コード例 #8
0
ファイル: test_http.c プロジェクト: gburiticato/kannel
static void client_thread(void *arg) 
{
    List *reqh;
    unsigned long i;
    long succeeded, failed;
    HTTPCaller *caller;
    char buf[1024];
    long in_queue;
    Counter *counter = NULL;

    caller = arg;
    succeeded = 0;
    failed = 0;
    reqh = gwlist_create();
    sprintf(buf, "%ld", (long) gwthread_self());
    http_header_add(reqh, "X-Thread", buf);
    if (auth_username != NULL && auth_password != NULL)
	http_add_basic_auth(reqh, auth_username, auth_password);

    in_queue = 0;
    counter = counter_create();
    
    for (;;) {
	    i = counter_increase(counter);
	    if (i >= max_requests)
	    	goto receive_rest;
	    start_request(caller, reqh, i);
	    if (interval > 0)
            gwthread_sleep(interval);
        ++in_queue;
	    if (receive_reply(caller) == -1)
	       ++failed;
    	else
	    	++succeeded;
	    --in_queue;
    }

receive_rest:
    while (in_queue > 0) {
	if (receive_reply(caller) == -1)
	    ++failed;
	else
	    ++succeeded;
    	--in_queue;
    }

    counter_destroy(counter);
    http_destroy_headers(reqh);
    http_caller_destroy(caller);
    info(0, "This thread: %ld succeeded, %ld failed.", succeeded, failed);
}
コード例 #9
0
ファイル: test_ppg.c プロジェクト: LeeVidor/kannel-mongodb
static void push_thread(void *arg)
{
    HTTPCaller *caller;
    long succeeded, failed, in_queue;
    unsigned long i;

    caller = arg;
    succeeded = 0;
    failed = 0;   
    in_queue = 0;
    i = 0;

    for (;;) {
        while (in_queue < MAX_IN_QUEUE) {
	        i = counter_increase(counter);
            if (i >= max_pushes)
	            goto receive_rest;
            start_push(caller, i);
            if (wait_seconds > 0)
                gwthread_sleep(wait_seconds);
            ++in_queue;
        }

        while (in_queue >= MAX_IN_QUEUE) {
	        if (receive_push_reply(caller) == -1)
	            ++failed;
            else
	            ++succeeded;
            --in_queue;
        }
    }

receive_rest:
    while (in_queue > 0) {
        if (receive_push_reply(caller) == -1)
	        ++failed;
        else
	        ++succeeded;
        --in_queue;
    }

    http_caller_destroy(caller);
    info(0, "TEST_PPG: In thread %ld %ld succeeded, %ld failed", 
         (long) gwthread_self(), succeeded, failed);
}
コード例 #10
0
ファイル: list.c プロジェクト: armic/erpts
int list_wait_until_nonempty(List *list)
{
    int ret;

    lock(list);
    while (list->len == 0 && list->num_producers > 0) {
        list->single_operation_lock->owner = -1;
        pthread_cond_wait(&list->nonempty,
                          &list->single_operation_lock->mutex);
        list->single_operation_lock->owner = gwthread_self();
    }
    if (list->len > 0)
        ret = 1;
    else
        ret = -1;
    unlock(list);
    return ret;
}
コード例 #11
0
static void new_thread_cleanup(void *arg)
{
    struct new_thread_args *p = arg;

    lock();
    debug("gwlib.gwthread", 0, "Thread %ld (%s) terminates.",
          p->ti->number, p->ti->name);
    alert_joiners();
#ifdef HAVE_LIBSSL
    /* Clear the OpenSSL thread-specific error queue to avoid
     * memory leaks. */
    ERR_remove_state(gwthread_self());
#endif /* HAVE_LIBSSL */
    /* Must free p before signaling our exit, otherwise there is
     * a race with gw_check_leaks at shutdown. */
    gw_free(p);
    delete_threadinfo();
    unlock();
}
コード例 #12
0
ファイル: list.c プロジェクト: armic/erpts
void *list_consume(List *list)
{
    void *item;

    lock(list);
    while (list->len == 0 && list->num_producers > 0) {
        list->single_operation_lock->owner = -1;
        pthread_cond_wait(&list->nonempty,
                          &list->single_operation_lock->mutex);
        list->single_operation_lock->owner = gwthread_self();
    }
    if (list->len > 0) {
        item = GET(list, 0);
        delete_items_from_list(list, 0, 1);
    } else {
        item = NULL;
    }
    unlock(list);
    return item;
}
コード例 #13
0
ファイル: gw-rwlock.c プロジェクト: Phonebooth/kannel
int gw_rwlock_unlock(RWLock *lock)
{
    int ret = 0;
    gw_assert(lock != NULL);

#ifdef HAVE_PTHREAD_RWLOCK
    ret = pthread_rwlock_unlock(&lock->rwlock);
    if (ret != 0)
        panic(ret, "Error while gw_rwlock_unlock.");
#else
    RWDEBUG("", 0, "------------ gw_rwlock_unlock(%p) ----------", lock);
    if (lock->writer == gwthread_self()) {
        lock->writer = -1;
        gwlist_unlock(lock->rwlock);
    } else 
        gwlist_remove_producer(lock->rwlock);
#endif

    return ret;
}
コード例 #14
0
ファイル: gw-rwlock.c プロジェクト: Phonebooth/kannel
int gw_rwlock_wrlock(RWLock *lock)
{
    int ret = 0;
    gw_assert(lock != NULL);

#ifdef HAVE_PTHREAD_RWLOCK
    ret = pthread_rwlock_wrlock(&lock->rwlock);
    if (ret != 0)
        panic(ret, "Error while pthread_rwlock_wrlock.");
#else
    RWDEBUG("", 0, "------------ gw_rwlock_wrlock(%p) ----------", lock);
    gwlist_lock(lock->rwlock);
    RWDEBUG("", 0, "------------ gw_rwlock_wrlock(%p) producers=%d", lock, gwlist_producer_count(lock->rwlock));
    /* wait for reader */
    gwlist_consume(lock->rwlock);
    lock->writer = gwthread_self();
#endif

    return ret;
}
コード例 #15
0
void *gw_prioqueue_consume(gw_prioqueue_t *queue)
{
    void *ret;
    
    gw_assert(queue != NULL);

    queue_lock(queue);
    while (queue->len == 1 && queue->producers > 0) {
        queue->mutex->owner = -1;
        pthread_cond_wait(&queue->nonempty, &queue->mutex->mutex);
        queue->mutex->owner = gwthread_self();
    }
    if (queue->len > 1) {
        ret = queue->tab[1]->item;
        gw_free(queue->tab[1]);
        queue->tab[1] = queue->tab[--queue->len];
        downheap(queue, 1);
    } else {
        ret = NULL;
    }
    queue_unlock(queue);
    
    return ret;
}
コード例 #16
0
static void format(char *buf, int level, const char *place, int e,
		   const char *fmt, int with_timestamp_and_pid)
{
    static char *tab[] = {
        "DEBUG: ",
        "INFO: ",
        "WARNING: ",
        "ERROR: ",
        "PANIC: ",
        "LOG: "
    };
    static int tab_size = sizeof(tab) / sizeof(tab[0]);
    time_t t;
    struct tm tm;
    char *p, prefix[1024];
    long tid, pid;
    
    p = prefix;

    if (with_timestamp_and_pid) {
        time(&t);
#if LOG_TIMESTAMP_LOCALTIME
        tm = gw_localtime(t);
#else
        tm = gw_gmtime(t);
#endif
        sprintf(p, "%04d-%02d-%02d %02d:%02d:%02d ",
        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
        tm.tm_hour, tm.tm_min, tm.tm_sec);

        p = strchr(p, '\0');

        /* print PID and thread ID */
        gwthread_self_ids(&tid, &pid);
        sprintf(p, "[%ld] [%ld] ", pid, tid);
    } else {
        /* thread ID only */
        tid = gwthread_self();
        sprintf(p, "[%ld] ", tid);
    }

    p = strchr(p, '\0');
    if (level < 0 || level >= tab_size)
        sprintf(p, "UNKNOWN: ");
    else
        sprintf(p, "%s", tab[level]);

    p = strchr(p, '\0');
    if (place != NULL && *place != '\0')
        sprintf(p, "%s: ", place);
    
    if (strlen(prefix) + strlen(fmt) > FORMAT_SIZE / 2) {
        sprintf(buf, "%s <OUTPUT message too long>\n", prefix);
        return;
    }
    
    if (e == 0)
        sprintf(buf, "%s%s\n", prefix, fmt);
    else
        sprintf(buf, "%s%s\n%sSystem error %d: %s\n",
                prefix, fmt, prefix, e, strerror(e));
}
コード例 #17
0
ファイル: gwthread-pthread.c プロジェクト: Phonebooth/kannel
/* Somewhat broken pthreads */ 
int gwthread_shouldhandlesignal(int signal){
    return (gwthread_self() == MAIN_THREAD_ID);
}