summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xine-engine/xine.c49
-rw-r--r--src/xine-engine/xine_internal.h9
2 files changed, 48 insertions, 10 deletions
diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c
index f49a988c9..612bf8dcc 100644
--- a/src/xine-engine/xine.c
+++ b/src/xine-engine/xine.c
@@ -127,23 +127,42 @@ void _x_extra_info_merge( extra_info_t *dst, extra_info_t *src ) {
}
}
-static void ticket_acquire(xine_ticket_t *this, int irrevocable) {
+static int ticket_acquire_internal(xine_ticket_t *this, int irrevocable, int nonblocking) {
+ int must_wait = 0;
pthread_mutex_lock(&this->lock);
if (this->ticket_revoked && !this->irrevocable_tickets)
- pthread_cond_wait(&this->issued, &this->lock);
+ must_wait = !nonblocking;
else if (this->atomic_revoke && !pthread_equal(this->atomic_revoker_thread, pthread_self()))
+ must_wait = 1;
+
+ if (must_wait) {
+ if (nonblocking) {
+ pthread_mutex_unlock(&this->lock);
+ return 0;
+ }
+
pthread_cond_wait(&this->issued, &this->lock);
+ }
this->tickets_granted++;
if (irrevocable)
this->irrevocable_tickets++;
pthread_mutex_unlock(&this->lock);
+ return 1;
}
-static void ticket_release(xine_ticket_t *this, int irrevocable) {
+static int ticket_acquire_nonblocking(xine_ticket_t *this, int irrevocable) {
+ return ticket_acquire_internal(this, irrevocable, 1);
+}
+
+static void ticket_acquire(xine_ticket_t *this, int irrevocable) {
+ ticket_acquire_internal(this, irrevocable, 0);
+}
+
+static void ticket_release_internal(xine_ticket_t *this, int irrevocable, int nonblocking) {
pthread_mutex_lock(&this->lock);
@@ -153,12 +172,20 @@ static void ticket_release(xine_ticket_t *this, int irrevocable) {
if (this->ticket_revoked && !this->tickets_granted)
pthread_cond_broadcast(&this->revoked);
- if (this->ticket_revoked && !this->irrevocable_tickets)
+ if (this->ticket_revoked && !this->irrevocable_tickets && !nonblocking)
pthread_cond_wait(&this->issued, &this->lock);
pthread_mutex_unlock(&this->lock);
}
+static void ticket_release_nonblocking(xine_ticket_t *this, int irrevocable) {
+ ticket_release_internal(this, irrevocable, 1);
+}
+
+static void ticket_release(xine_ticket_t *this, int irrevocable) {
+ ticket_release_internal(this, irrevocable, 0);
+}
+
static void ticket_renew(xine_ticket_t *this, int irrevocable) {
pthread_mutex_lock(&this->lock);
@@ -227,12 +254,14 @@ static xine_ticket_t *ticket_init(void) {
port_ticket = (xine_ticket_t *) xine_xmalloc(sizeof(xine_ticket_t));
- port_ticket->acquire = ticket_acquire;
- port_ticket->release = ticket_release;
- port_ticket->renew = ticket_renew;
- port_ticket->issue = ticket_issue;
- port_ticket->revoke = ticket_revoke;
- port_ticket->dispose = ticket_dispose;
+ port_ticket->acquire_nonblocking = ticket_acquire_nonblocking;
+ port_ticket->acquire = ticket_acquire;
+ port_ticket->release_nonblocking = ticket_release_nonblocking;
+ port_ticket->release = ticket_release;
+ port_ticket->renew = ticket_renew;
+ port_ticket->issue = ticket_issue;
+ port_ticket->revoke = ticket_revoke;
+ port_ticket->dispose = ticket_dispose;
pthread_mutex_init(&port_ticket->lock, NULL);
pthread_mutex_init(&port_ticket->revoke_lock, NULL);
diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h
index 30899a4b3..da6f88a7f 100644
--- a/src/xine-engine/xine_internal.h
+++ b/src/xine-engine/xine_internal.h
@@ -159,6 +159,15 @@ struct xine_ticket_s {
* revocation or by other threads acquiring tickets */
void (*revoke)(xine_ticket_t *self, int atomic);
+ /* behaves like acquire() but doesn't block the calling thread; when
+ * the thread would have been blocked, 0 is returned otherwise 1
+ * this function acquires a ticket even if ticket revocation is active */
+ int (*acquire_nonblocking)(xine_ticket_t *self, int irrevocable);
+
+ /* behaves like release() but doesn't block the calling thread; should
+ * be used in combination with acquire_nonblocking() */
+ void (*release_nonblocking)(xine_ticket_t *self, int irrevocable);
+
void (*dispose)(xine_ticket_t *self);
pthread_mutex_t lock;