Bug #324 » pthread_cond_patch.diff
src/bin/lttng-sessiond/consumer.h | ||
---|---|---|
#ifndef _CONSUMER_H
|
||
#define _CONSUMER_H
|
||
#include <semaphore.h>
|
||
#include <common/consumer.h>
|
||
#include <common/hashtable/hashtable.h>
|
||
#include <lttng/lttng.h>
|
||
... | ... | |
enum lttng_consumer_type type;
|
||
pthread_t thread; /* Worker thread interacting with the consumer */
|
||
sem_t sem;
|
||
/* Conditions used by the consumer thread to indicate readiness. */
|
||
pthread_cond_t cond;
|
||
pthread_condattr_t condattr;
|
||
pthread_mutex_t cond_mutex;
|
||
/* Mutex to control consumerd pid assignation */
|
||
pthread_mutex_t pid_mutex;
|
src/bin/lttng-sessiond/main.c | ||
---|---|---|
#include <grp.h>
|
||
#include <limits.h>
|
||
#include <pthread.h>
|
||
#include <semaphore.h>
|
||
#include <signal.h>
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
... | ... | |
.cmd_sock = -1,
|
||
.pid_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||
.cond = PTHREAD_COND_INITIALIZER,
|
||
.cond_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||
};
|
||
static struct consumer_data ustconsumer64_data = {
|
||
.type = LTTNG_CONSUMER64_UST,
|
||
... | ... | |
.cmd_sock = -1,
|
||
.pid_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||
.cond = PTHREAD_COND_INITIALIZER,
|
||
.cond_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||
};
|
||
static struct consumer_data ustconsumer32_data = {
|
||
.type = LTTNG_CONSUMER32_UST,
|
||
... | ... | |
.cmd_sock = -1,
|
||
.pid_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||
.cond = PTHREAD_COND_INITIALIZER,
|
||
.cond_mutex = PTHREAD_MUTEX_INITIALIZER,
|
||
};
|
||
/* Shared between threads */
|
||
... | ... | |
consumer_data->cmd_sock =
|
||
lttcomm_connect_unix_sock(consumer_data->cmd_unix_sock_path);
|
||
if (consumer_data->cmd_sock < 0) {
|
||
sem_post(&consumer_data->sem);
|
||
pthread_cond_signal(&consumer_data->cond);
|
||
PERROR("consumer connect");
|
||
goto error;
|
||
}
|
||
/* Signal condition to tell that the kconsumerd is ready */
|
||
sem_post(&consumer_data->sem);
|
||
pthread_cond_signal(&consumer_data->cond);
|
||
DBG("consumer command socket ready");
|
||
} else {
|
||
ERR("consumer error when waiting for SOCK_READY : %s",
|
||
... | ... | |
int ret;
|
||
struct timespec timeout;
|
||
timeout.tv_sec = DEFAULT_SEM_WAIT_TIMEOUT;
|
||
timeout.tv_nsec = 0;
|
||
/* Setup pthread condition */
|
||
ret = pthread_condattr_init(&consumer_data->condattr);
|
||
if (ret != 0) {
|
||
errno = ret;
|
||
PERROR("pthread_condattr_init consumer data");
|
||
goto error;
|
||
}
|
||
/* Setup semaphore */
|
||
ret = sem_init(&consumer_data->sem, 0, 0);
|
||
if (ret < 0) {
|
||
PERROR("sem_init consumer semaphore");
|
||
/*
|
||
* Set the monotonic clock in order to make sure we DO NOT jump in time
|
||
* between the clock_gettime() call and the timedwait call. See bug #324
|
||
* for a more details and how we noticed it.
|
||
*/
|
||
ret = pthread_condattr_setclock(&consumer_data->condattr, CLOCK_MONOTONIC);
|
||
if (ret != 0) {
|
||
errno = ret;
|
||
PERROR("pthread_condattr_setclock consumer data");
|
||
goto error;
|
||
}
|
||
ret = pthread_cond_init(&consumer_data->cond, &consumer_data->condattr);
|
||
if (ret != 0) {
|
||
errno = ret;
|
||
PERROR("pthread_cond_init consumer data");
|
||
goto error;
|
||
}
|
||
... | ... | |
goto error;
|
||
}
|
||
/* We are about to wait on a pthread condition */
|
||
pthread_mutex_lock(&consumer_data->cond_mutex);
|
||
/* Get time for sem_timedwait absolute timeout */
|
||
ret = clock_gettime(CLOCK_REALTIME, &timeout);
|
||
ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
|
||
if (ret < 0) {
|
||
PERROR("clock_gettime spawn consumer");
|
||
/* Infinite wait for the kconsumerd thread to be ready */
|
||
ret = sem_wait(&consumer_data->sem);
|
||
ret = pthread_cond_wait(&consumer_data->cond,
|
||
&consumer_data->cond_mutex);
|
||
} else {
|
||
/* Normal timeout if the gettime was successful */
|
||
timeout.tv_sec += DEFAULT_SEM_WAIT_TIMEOUT;
|
||
ret = sem_timedwait(&consumer_data->sem, &timeout);
|
||
ret = pthread_cond_timedwait(&consumer_data->cond,
|
||
&consumer_data->cond_mutex, &timeout);
|
||
}
|
||
if (ret < 0) {
|
||
if (errno == ETIMEDOUT) {
|
||
pthread_mutex_unlock(&consumer_data->cond_mutex);
|
||
if (ret != 0) {
|
||
errno = ret;
|
||
if (ret == ETIMEDOUT) {
|
||
/*
|
||
* Call has timed out so we kill the kconsumerd_thread and return
|
||
* an error.
|
||
*/
|
||
ERR("The consumer thread was never ready. Killing it");
|
||
ERR("Condition timed out. The consumer thread was never ready."
|
||
" Killing it");
|
||
ret = pthread_cancel(consumer_data->thread);
|
||
if (ret < 0) {
|
||
PERROR("pthread_cancel consumer thread");
|
||
}
|
||
} else {
|
||
PERROR("semaphore wait failed consumer thread");
|
||
PERROR("pthread_cond_wait failed consumer thread");
|
||
}
|
||
goto error;
|
||
}
|
- « Previous
- 1
- …
- 3
- 4
- 5
- Next »