summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Auras <yak54@inkennet.de>2011-03-04 00:12:11 +0100
committerAndreas Auras <yak54@inkennet.de>2011-03-04 00:12:11 +0100
commit00289bd75d4894ebdddfe8c13600faffd59c339b (patch)
tree368b3cccad6e252f1fc3b628f683fcba7922c342
parentf75f91ce18bd63eb553671428d63411d625abdc9 (diff)
downloadxine-lib-atmolight-00289bd75d4894ebdddfe8c13600faffd59c339b.tar.gz
xine-lib-atmolight-00289bd75d4894ebdddfe8c13600faffd59c339b.tar.bz2
Added synchronize condition for safer waiting of thread stop
-rw-r--r--xine_post_atmo.c53
1 files changed, 34 insertions, 19 deletions
diff --git a/xine_post_atmo.c b/xine_post_atmo.c
index 91a5abf..4fe6813 100644
--- a/xine_post_atmo.c
+++ b/xine_post_atmo.c
@@ -204,7 +204,7 @@ typedef struct atmo_post_plugin_s
int *grab_running, *output_running;
pthread_t grab_thread, output_thread;
pthread_mutex_t lock;
- pthread_cond_t thread_started;
+ pthread_cond_t thread_started, thread_stopped;
/* output related */
output_driver_t *output_driver;
@@ -949,8 +949,8 @@ static void *atmo_grab_loop (void *this_gen) {
free(weight);
pthread_mutex_lock(&this->lock);
- if (running)
- this->grab_running = NULL;
+ this->grab_running = NULL;
+ pthread_cond_broadcast(&this->thread_stopped);
pthread_mutex_unlock(&this->lock);
_x_post_dec_usage(port);
@@ -1207,8 +1207,8 @@ static void *atmo_output_loop (void *this_gen) {
ticket->release(ticket, 0);
pthread_mutex_lock(&this->lock);
- if (running)
- this->output_running = NULL;
+ this->output_running = NULL;
+ pthread_cond_broadcast(&this->thread_stopped);
pthread_mutex_unlock(&this->lock);
_x_post_dec_usage(port);
@@ -1306,23 +1306,36 @@ static void start_threads(atmo_post_plugin_t *this) {
}
-static void stop_threads(atmo_post_plugin_t *this, int wait) {
- int do_wait = 0;
-
+static void stop_threads(atmo_post_plugin_t *this) {
pthread_mutex_lock(&this->lock);
- if (this->grab_running) {
+ if (this->grab_running)
*this->grab_running = 0;
- this->grab_running = NULL;
- do_wait = wait;
- }
- if (this->output_running) {
+ if (this->output_running)
*this->output_running = 0;
- this->output_running = NULL;
- do_wait = wait;
+ if (this->grab_running || this->output_running) {
+ struct timeval tvnow, tvdiff, tvtimeout;
+ struct timespec ts;
+
+ /* calculate absolute timeout time */
+ tvdiff.tv_sec = THREAD_TERMINATION_WAIT_TIME / 1000;
+ tvdiff.tv_usec = THREAD_TERMINATION_WAIT_TIME % 1000;
+ tvdiff.tv_usec *= 1000;
+ gettimeofday(&tvnow, NULL);
+ timeradd(&tvnow, &tvdiff, &tvtimeout);
+ ts.tv_sec = tvtimeout.tv_sec;
+ ts.tv_nsec = tvtimeout.tv_usec;
+ ts.tv_nsec *= 1000;
+
+ while (this->grab_running || this->output_running) {
+ if (pthread_cond_timedwait(&this->thread_stopped, &this->lock, &ts) == ETIMEDOUT) {
+ llprintf(LOG_1, "timeout while waiting for thread stop!\n");
+ break;
+ }
+ }
}
+ this->grab_running = NULL;
+ this->output_running = NULL;
pthread_mutex_unlock(&this->lock);
- if (do_wait)
- usleep(THREAD_TERMINATION_WAIT_TIME*1000);
}
@@ -1430,7 +1443,7 @@ static void atmo_video_close(xine_video_port_t *port_gen, xine_stream_t *stream)
atmo_post_plugin_t *this = (atmo_post_plugin_t *) port->post;
pthread_mutex_lock(&this->port_lock);
- stop_threads(this, 1);
+ stop_threads(this);
this->port = NULL;
port->original_port->close(port->original_port, stream);
port->stream = NULL;
@@ -1485,7 +1498,7 @@ static int atmo_set_parameters(xine_post_t *this_gen, void *parm_gen)
}
} else {
if (this->active_parm.enabled) {
- stop_threads(this, 1);
+ stop_threads(this);
close_output_driver(this);
}
}
@@ -1530,6 +1543,7 @@ static void atmo_dispose(post_plugin_t *this_gen)
pthread_mutex_destroy(&this->lock);
pthread_mutex_destroy(&this->port_lock);
pthread_cond_destroy(&this->thread_started);
+ pthread_cond_destroy(&this->thread_stopped);
free(this);
}
}
@@ -1581,6 +1595,7 @@ static post_plugin_t *atmo_open_plugin(post_class_t *class_gen,
pthread_mutex_init(&this->lock, NULL);
pthread_mutex_init(&this->port_lock, NULL);
pthread_cond_init(&this->thread_started, NULL);
+ pthread_cond_init(&this->thread_stopped, NULL);
/* Set default values for parameters */
this->parm.enabled = 1;