summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorphintuka <phintuka>2008-11-16 21:36:46 +0000
committerphintuka <phintuka>2008-11-16 21:36:46 +0000
commitebaeff6eea285133a4b116fe15a565f1cbef3f33 (patch)
tree160363059b0fff08537d07563f47519abe120e2e
parent3d21d2e3efe594741d7da86439763e152c4ef67b (diff)
downloadxineliboutput-ebaeff6eea285133a4b116fe15a565f1cbef3f33.tar.gz
xineliboutput-ebaeff6eea285133a4b116fe15a565f1cbef3f33.tar.bz2
Implement thread cancellation safe locking (mutexes are unlocked if thread is cancelled).
Changed vdr_plugin_keypress so that it can be cancelled.
-rw-r--r--xine_input_vdr.c63
1 files changed, 52 insertions, 11 deletions
diff --git a/xine_input_vdr.c b/xine_input_vdr.c
index fd1056fb..fb8ff3d8 100644
--- a/xine_input_vdr.c
+++ b/xine_input_vdr.c
@@ -4,7 +4,7 @@
* See the main source file 'xineliboutput.c' for copyright information and
* how to reach the author.
*
- * $Id: xine_input_vdr.c,v 1.195 2008-11-16 15:27:54 rofafor Exp $
+ * $Id: xine_input_vdr.c,v 1.196 2008-11-16 21:36:46 phintuka Exp $
*
*/
@@ -412,6 +412,42 @@ static void flush_udp_data(udp_data_t *data)
}
#endif
+/********************* cancellable mutex locking *************************/
+
+/*
+ * mutex cleanup()
+ *
+ * Unlock mutex. Used as thread cleanup handler.
+ */
+static void mutex_cleanup(void *arg)
+{
+ pthread_mutex_unlock((pthread_mutex_t *)arg);
+}
+
+/*
+ * mutex_lock_cancellable() / mutex_unlock_cancellable()
+ *
+ * mutex lock/unlock for cancellable sections
+ *
+ * - do not enter protected section if locking fails
+ * - unlock mutex if thread is cancelled while holding the lock
+ *
+ * - lock/unlock must be used pairwise within the same lexical scope !
+ *
+ */
+#define mutex_lock_cancellable(mutex) \
+ if (pthread_mutex_lock(mutex)) { \
+ LOGERR("pthread_mutex_lock (%s) failed, skipping locked block !", #mutex); \
+ } else { \
+ pthread_cleanup_push(mutex_cleanup, (void*) mutex);
+
+#define mutex_unlock_cancellable(mutex) \
+ if (pthread_mutex_unlock(mutex)) \
+ LOGERR("pthread_mutex_unlock (%s) failed !", #mutex); \
+ pthread_cleanup_pop(0); \
+ }
+
+
#ifdef ADJUST_SCR_SPEED
/******************************* SCR *************************************
*
@@ -1071,9 +1107,9 @@ static void write_control_data(vdr_input_plugin_t *this, const void *str, size_t
static void write_control(vdr_input_plugin_t *this, const char *str)
{
size_t len = strlen(str);
- pthread_mutex_lock (&this->fd_control_lock);
+ mutex_lock_cancellable (&this->fd_control_lock);
write_control_data(this, str, len);
- pthread_mutex_unlock (&this->fd_control_lock);
+ mutex_unlock_cancellable (&this->fd_control_lock);
}
static void printf_control(vdr_input_plugin_t *this, const char *fmt, ...)
@@ -3035,11 +3071,10 @@ static int handle_control_grab(vdr_input_plugin_t *this, const char *cmd)
if(data && data->size>0 && data->data) {
char s[128];
sprintf(s, "GRAB %d %lu\r\n", this->token, (unsigned long)data->size);
- pthread_mutex_lock (&this->fd_control_lock);
+ mutex_lock_cancellable (&this->fd_control_lock);
write_control_data(this, s, strlen(s));
write_control_data(this, data->data, data->size);
- if(pthread_mutex_unlock (&this->fd_control_lock))
- LOGERR("pthread_mutex_unlock failed");
+ mutex_unlock_cancellable (&this->fd_control_lock);
} else {
/* failed */
printf_control(this, "GRAB %d 0\r\n", this->token);
@@ -4809,15 +4844,21 @@ static int vdr_plugin_write(vdr_input_plugin_if_t *this_if, const char *data, in
return len;
}
+/*
+ * vdr_plugin_keypress()
+ *
+ * - Called by frontend and vdr_event_cb()
+ * - forward xine-lib/frontend-generated input events to VDR
+ *
+ * It is safe to cancel thread while this function is being executed.
+ */
static int vdr_plugin_keypress(vdr_input_plugin_if_t *this_if,
const char *map, const char *key,
int repeat, int release)
{
vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_if;
- if(pthread_mutex_lock(&this->lock)) {
- LOGERR("vdr_plugin_keypress: pthread_mutex_lock failed");
- return -1;
- }
+
+ mutex_lock_cancellable(&this->lock);
if(key && this->fd_control >= 0) {
if(map)
@@ -4827,7 +4868,7 @@ static int vdr_plugin_keypress(vdr_input_plugin_if_t *this_if,
printf_control(this, "KEY %s\r\n", key);
}
- pthread_mutex_unlock(&this->lock);
+ mutex_unlock_cancellable(&this->lock);
return 0;
}