Ejemplo n.º 1
0
void wait_for_more_jobs(void)
{
thread_mutex_lock(&jobs_mutex);
if(jobs_submitted==jobs_done){
	thread_cond_wait(&wait_for_more_jobs_condition, &jobs_mutex); 
	}
thread_mutex_unlock(&jobs_mutex);
}
Ejemplo n.º 2
0
/**
 * Retrieves the next item from the queue. If there are no
 * items available, it will block until one becomes available.
 * Once retrieved, the item is placed into the address specified by
 * 'data'.
 */
int queue_pop(queue_t *queue, void **data)
{
    int rv;

    if (queue->terminated) {
        return QUEUE_EOF; /* no more elements ever again */
    }

    rv = thread_mutex_lock(queue->one_big_mutex);
    if (rv != 0) {
        return rv;
    }

    /* Keep waiting until we wake up and find that the queue is not empty. */
    if (queue_empty(queue)) {
        if (!queue->terminated) {
            queue->empty_waiters++;
            rv = thread_cond_wait(queue->not_empty, queue->one_big_mutex);
            queue->empty_waiters--;
            if (rv != 0) {
                thread_mutex_unlock(queue->one_big_mutex);
                return rv;
            }
        }
        /* If we wake up and it's still empty, then we were interrupted */
        if (queue_empty(queue)) {
            rv = thread_mutex_unlock(queue->one_big_mutex);
            if (rv != 0) {
                return rv;
            }
            if (queue->terminated) {
                return QUEUE_EOF; /* no more elements ever again */
            }
            else {
                return QUEUE_EINTR;
            }
        }
    } 

    *data = queue->data[queue->out];
    queue->nelts--;

    queue->out = (queue->out + 1) % queue->bounds;
    if (queue->full_waiters) {
        rv = thread_cond_signal(queue->not_full);
        if (rv != 0) {
            thread_mutex_unlock(queue->one_big_mutex);
            return rv;
        }
    }

    rv = thread_mutex_unlock(queue->one_big_mutex);
    return rv;
}
Ejemplo n.º 3
0
/**
 * Push new data onto the queue. Blocks if the queue is full. Once
 * the push operation has completed, it signals other threads waiting
 * in queue_pop() that they may continue consuming sockets.
 */
int queue_push(queue_t *queue, void *data)
{
    int rv;

    if (queue->terminated) {
        return QUEUE_EOF; /* no more elements ever again */
    }

    rv = thread_mutex_lock(queue->one_big_mutex);
    if (rv != 0) {
        return rv;
    }

    if (queue_full(queue)) {
        if (!queue->terminated) {
            queue->full_waiters++;
            rv = thread_cond_wait(queue->not_full, queue->one_big_mutex);
            queue->full_waiters--;
            if (rv != 0) {
                thread_mutex_unlock(queue->one_big_mutex);
                return rv;
            }
        }
        /* If we wake up and it's still empty, then we were interrupted */
        if (queue_full(queue)) {
            rv = thread_mutex_unlock(queue->one_big_mutex);
            if (rv != 0) {
                return rv;
            }
            if (queue->terminated) {
                return QUEUE_EOF; /* no more elements ever again */
            }
            else {
                return QUEUE_EINTR;
            }
        }
    }

    queue->data[queue->in] = data;
    queue->in = (queue->in + 1) % queue->bounds;
    queue->nelts++;

    if (queue->empty_waiters) {
        rv = thread_cond_signal(queue->not_empty);
        if (rv != 0) {
            thread_mutex_unlock(queue->one_big_mutex);
            return rv;
        }
    }

    rv = thread_mutex_unlock(queue->one_big_mutex);
    return rv;
}
Ejemplo n.º 4
0
void wait_for_all_done(void)
{
thread_mutex_lock(&jobs_mutex);
if(jobs_submitted==jobs_done) {
	jobs_free=0;
	next_job_to_do=0;
	thread_mutex_unlock(&jobs_mutex);
	return;
	}
thread_cond_wait(&all_done_condition, &jobs_mutex);
thread_mutex_unlock(&jobs_mutex);
}
Ejemplo n.º 5
0
void *thread_cruncher(int i)
{

while(1) {
	wait_for_more_jobs();
	thread_mutex_lock(&thread_num_mutex);
	while(i>=num_threads)thread_cond_wait(&thread_not_needed, &thread_num_mutex);
	thread_mutex_unlock(&thread_num_mutex);
	while(do_single_job(i));
	}

return NULL; /* make compiler happy */
}
Ejemplo n.º 6
0
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
    if (cond == NULL || mutex == NULL)
        return_errno(EINVAL, EINVAL);
    if (*cond == PTHREAD_COND_INITIALIZER)
        if (pthread_cond_init(cond, NULL) != OK)
            return errno;
    if (*mutex == PTHREAD_MUTEX_INITIALIZER)
        if (pthread_mutex_init(mutex, NULL) != OK)
            return errno;
    if (!thread_cond_wait((cond_t *)(*cond), (mutex_t *)(*mutex)))
        return errno;
    return OK;
}
Ejemplo n.º 7
0
static int
channel_get (lua_State *L)
{
    struct channel *chan = checkudata(L, 1, CHANNEL_TYPENAME);
    const msec_t timeout = lua_isnoneornil(L, 2)
     ? TIMEOUT_INFINITE : (msec_t) lua_tointeger(L, 2);
    int nput;
    int idx;
    int i;

    lua_settop(L, 1);
    lua_getfenv(L, 1);  /* storage */
    lua_insert(L, 1);

    sys_vm_leave();

    thread_critsect_enter(&chan->mutex);
    thread_cond_signal(&chan->get);

    /* wait signal */
    while (chan->n == 0) {
        thread_cond_wait(&chan->put, &chan->mutex, timeout);
    }

    /* get from storage */
    idx = chan->idx + 1;

    lua_rawgeti(L, 1, idx);
    nput = lua_tointeger(L, -1);
    lua_pushnil(L);
    lua_rawseti(L, 1, idx);
    chan->idx = idx + nput;

    for (i = chan->idx; i > idx; --i) {
        lua_rawgeti(L, 1, i);
        lua_pushnil(L);
        lua_rawseti(L, 1, i);
    }

    if (chan->idx == chan->top) chan->idx = chan->top = 0;
    chan->n--;

    thread_critsect_leave(&chan->mutex);

    sys_vm_enter();

    return nput;
}
Ejemplo n.º 8
0
void *stats_connection(void *arg)
{
    stats_connection_t *statcon = (stats_connection_t *)arg;
    stats_event_t *local_event_queue = NULL;
    mutex_t local_event_mutex;
    stats_event_t *event;

    /* increment the thread count */
    thread_mutex_lock(&_stats_mutex);
    _stats_threads++;
    thread_mutex_unlock(&_stats_mutex);

    thread_mutex_create(&local_event_mutex);

    _atomic_get_and_register(&local_event_queue, &local_event_mutex);

    while (_stats_running) {
        thread_mutex_lock(&local_event_mutex);
        event = _get_event_from_queue(&local_event_queue);
        if (event != NULL) {
            if (!_send_event_to_client(event, statcon->con)) {
                _free_event(event);
                thread_mutex_unlock(&local_event_mutex);
                break;
            }
            _free_event(event);
        } else {
            thread_mutex_unlock(&local_event_mutex);
            thread_cond_wait(&_event_signal_cond);
            continue;
        }
                   
        thread_mutex_unlock(&local_event_mutex);
    }

    thread_mutex_destroy(&local_event_mutex);

    thread_mutex_lock(&_stats_mutex);
    _stats_threads--;
    thread_mutex_unlock(&_stats_mutex);

    thread_exit(0);
    
    return NULL;
}
Ejemplo n.º 9
0
/* this returns queued clients for the connection thread. headers are
 * already provided, but need to be parsed.
 */
static connection_queue_t *_get_connection(void)
{
    connection_queue_t *node = NULL;

    /* common case, no new connections so don't bother taking locks */
    if (_con_queue) {
        node = (connection_queue_t *)_con_queue;
        _con_queue = node->next;
        if (_con_queue == NULL)
            _con_queue_tail = &_con_queue;
        node->next = NULL;
    } else {
        INFO("sleeping");
        thread_cond_wait(_connection_cond);
        INFO("awake");
    }
    return node;
}
Ejemplo n.º 10
0
ref_buffer *stream_wait_for_data(instance_t *stream)
{
    ref_buffer *buffer;
    queue_item *old;

    thread_mutex_lock(&stream->queue->lock);
    while(!stream->queue->head && !ices_config->shutdown && !stream->kill)
    {
        thread_mutex_unlock(&stream->queue->lock);
        thread_cond_wait(&ices_config->queue_cond);
        thread_mutex_lock(&stream->queue->lock);
    }

    if(ices_config->shutdown || stream->kill)
    {
        LOG_DEBUG0("Shutdown signalled: thread shutting down");
        thread_mutex_unlock(&stream->queue->lock);
        return NULL;
    }

    buffer = stream->queue->head->buf;
    old = stream->queue->head;

    stream->queue->head = stream->queue->head->next;
    if(!stream->queue->head)
        stream->queue->tail = NULL;

    free(old);
    stream->queue->length--;
    thread_mutex_unlock(&stream->queue->lock);

    /* ok, we pulled something off the queue and the queue is
     * now empty - this means we're probably keeping up, so
     * clear one of the errors. This way, very occasional errors
     * don't cause eventual shutdown
     */
    if(!stream->queue->head && stream->buffer_failures>0)
        stream->buffer_failures--;

    return buffer;
}
Ejemplo n.º 11
0
input_buffer *runner_wait_for_data(struct runner *run)
{
    input_buffer *ib;

#ifdef USE_PIPES
    if (read (run->fd[0], &ib, sizeof (ib)) < (ssize_t)sizeof (ib))
        return NULL;
#else
    while (run->pending == NULL || (run->pending && run->pending->next == NULL))
    {
        thread_cond_wait (&run->data_available);
        if (ices_config->shutdown)
            return NULL;
    }

    ib = run->pending;
    run->pending = ib->next;
    ib->next = NULL;
#endif

    return ib;
}
Ejemplo n.º 12
0
static int
channel_put (lua_State *L)
{
    struct sys_thread *td = sys_get_thread();
    struct channel *chan = checkudata(L, 1, CHANNEL_TYPENAME);
    int nput = lua_gettop(L) - 1;

    if (!td) luaL_argerror(L, 0, "Threading not initialized");
    if (!nput) luaL_argerror(L, 2, "data expected");

    lua_getfenv(L, 1);  /* get the storage table */
    lua_insert(L, 1);

    sys_vm_leave();

    thread_critsect_enter(&chan->mutex);
    thread_cond_signal(&chan->put);

    /* move the data to storage */
    {
	int top = chan->top;

	lua_pushinteger(L, nput);
	do {
	    lua_rawseti(L, 1, ++top);
	} while (nput--);
	chan->top = top;
        chan->n++;
    }

    while (chan->n > chan->max) {
        thread_cond_wait(&chan->get, &chan->mutex, TIMEOUT_INFINITE);
    }

    thread_critsect_leave(&chan->mutex);

    sys_vm_enter();
    return 0;
}
Ejemplo n.º 13
0
void *metadata_thread_signal(void *arg)
{
    char buf[1024];
    input_module_t *mod = arg;

    while(1)
    {
        char **md = NULL;
        int comments = 0;
        FILE *file;

        while(metadata_update_signalled == 0)
        {
            thread_cond_wait(&ices_config->event_pending_cond);
            if (ices_config->shutdown)
            {
                LOG_INFO0 ("metadata thread shutting down");
                return NULL;
            }
            LOG_DEBUG0("meta thread wakeup");
        }

        metadata_update_signalled = 0;

        file = fopen(ices_config->metadata_filename, "r");
        if(!file) {
            LOG_WARN2("Failed to open file \"%s\" for metadata update: %s", 
                    ices_config->metadata_filename, strerror(errno));
            continue;
        }

        LOG_DEBUG1("reading metadata from \"%s\"", ices_config->metadata_filename);
        while(fgets(buf, 1024, file))
        {
            if(buf[0] == '\n')
                break;
            else
            {
                if(buf[strlen(buf)-1] == '\n')
                    buf[strlen(buf)-1] = 0;
                md = realloc(md, (comments+2)*sizeof(char *));
                md[comments] = malloc(strlen(buf)+1);

                memcpy(md[comments], buf, strlen(buf)+1);
                comments++;
                LOG_INFO2 ("tag %d is %s", comments, buf);
            }
        }

        fclose(file);

        if(md) /* Don't update if there's nothing there */
        {
            md[comments]=0;

            /* Now, let's actually use the new data */
            LOG_INFO0("Updating metadata");
            mod->handle_event(mod,EVENT_METADATAUPDATE,md);
        }
        else
            LOG_INFO0("No metadata has been read");

    }
}
Ejemplo n.º 14
0
inline bool tuple_fifo::wait_for_writer(int timeout_ms) {
    _num_waits_on_remove++;
    return thread_cond_wait(_reader_notify, _lock, timeout_ms);
}
Ejemplo n.º 15
0
inline void tuple_fifo::wait_for_reader() {
    _num_waits_on_insert++;
    thread_cond_wait(_writer_notify, _lock);
}