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); }
/** * 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; }
/** * 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; }
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); }
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 */ }
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; }
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; }
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; }
/* 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; }
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; }
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; }
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; }
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"); } }
inline bool tuple_fifo::wait_for_writer(int timeout_ms) { _num_waits_on_remove++; return thread_cond_wait(_reader_notify, _lock, timeout_ms); }
inline void tuple_fifo::wait_for_reader() { _num_waits_on_insert++; thread_cond_wait(_writer_notify, _lock); }