summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorThibaut Mattern <tmattern@users.sourceforge.net>2003-10-14 22:16:32 +0000
committerThibaut Mattern <tmattern@users.sourceforge.net>2003-10-14 22:16:32 +0000
commit5233af2142e5fd045f922a82fef0c76c62684a7b (patch)
treec1b767730eb7360794c51b1af7b78e4d43fca18c /src
parent90a24be6db150d94d8ceea2b1f56dff8a2880d01 (diff)
downloadxine-lib-5233af2142e5fd045f922a82fef0c76c62684a7b.tar.gz
xine-lib-5233af2142e5fd045f922a82fef0c76c62684a7b.tar.bz2
Add a callback to the buffer_pool_alloc function.
The goal is to detect in the net_buf_ctrl if there is no more free buffer in a fifo, which indicates there will be a deadlock if the engine is not unpaused. Currently this detection is done from the "put" callback, it's not a safe solution, nothing prevents a demuxer to allocate 2 buffers before calling put(). The impact is low, only one test per buffer_pool_alloc call if no callback is registered. It's done exactly the same way as the put and get callbacks. CVS patchset: 5520 CVS date: 2003/10/14 22:16:32
Diffstat (limited to 'src')
-rw-r--r--src/xine-engine/buffer.c78
-rw-r--r--src/xine-engine/buffer.h11
2 files changed, 70 insertions, 19 deletions
diff --git a/src/xine-engine/buffer.c b/src/xine-engine/buffer.c
index fb12fca94..f32ff4b84 100644
--- a/src/xine-engine/buffer.c
+++ b/src/xine-engine/buffer.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: buffer.c,v 1.30 2003/05/15 20:23:18 miguelfreitas Exp $
+ * $Id: buffer.c,v 1.31 2003/10/14 22:16:32 tmattern Exp $
*
*
* contents:
@@ -72,9 +72,13 @@ static void buffer_pool_free (buf_element_t *element) {
static buf_element_t *buffer_pool_alloc (fifo_buffer_t *this) {
buf_element_t *buf;
+ int i;
pthread_mutex_lock (&this->buffer_pool_mutex);
+ for(i = 0; this->alloc_cb[i]; i++)
+ this->alloc_cb[i](this, this->alloc_cb_data[i]);
+
/* we always keep one free buffer for emergency situations like
* decoder flushes that would need a buffer in buffer_pool_try_alloc() */
while (this->buffer_pool_num_free < 2) {
@@ -336,6 +340,25 @@ static void fifo_buffer_dispose (fifo_buffer_t *this) {
}
/*
+ * Register an "alloc" callback
+ */
+static void fifo_register_alloc_cb (fifo_buffer_t *this,
+ void (*cb)(fifo_buffer_t *this,
+ void *data_cb),
+ void *data_cb) {
+ int i;
+ pthread_mutex_lock(&this->mutex);
+ for(i = 0; this->alloc_cb[i]; i++)
+ ;
+ if( i != BUF_MAX_CALLBACKS-1 ) {
+ this->alloc_cb[i] = cb;
+ this->alloc_cb_data[i] = data_cb;
+ this->alloc_cb[i+1] = NULL;
+ }
+ pthread_mutex_unlock(&this->mutex);
+}
+
+/*
* Register a "put" callback
*/
static void fifo_register_put_cb (fifo_buffer_t *this,
@@ -376,6 +399,25 @@ static void fifo_register_get_cb (fifo_buffer_t *this,
}
/*
+ * Unregister an "alloc" callback
+ */
+static void fifo_unregister_alloc_cb (fifo_buffer_t *this,
+ void (*cb)(fifo_buffer_t *this,
+ void *data_cb) ) {
+ int i,j;
+ pthread_mutex_lock(&this->mutex);
+ for(i = 0; this->alloc_cb[i]; i++) {
+ if( this->alloc_cb[i] == cb ) {
+ for(j = i; this->alloc_cb[j]; j++) {
+ this->alloc_cb[j] = this->alloc_cb[j+1];
+ this->alloc_cb_data[j] = this->alloc_cb_data[j+1];
+ }
+ }
+ }
+ pthread_mutex_unlock(&this->mutex);
+}
+
+/*
* Unregister a "put" callback
*/
static void fifo_unregister_put_cb (fifo_buffer_t *this,
@@ -427,21 +469,23 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
this = xine_xmalloc (sizeof (fifo_buffer_t));
- this->first = NULL;
- this->last = NULL;
- this->fifo_size = 0;
- this->put = fifo_buffer_put;
- this->insert = fifo_buffer_insert;
- this->get = fifo_buffer_get;
- this->clear = fifo_buffer_clear;
- this->size = fifo_buffer_size;
- this->num_free = fifo_buffer_num_free;
- this->data_size = fifo_buffer_data_size;
- this->dispose = fifo_buffer_dispose;
- this->register_get_cb = fifo_register_get_cb;
- this->register_put_cb = fifo_register_put_cb;
- this->unregister_get_cb = fifo_unregister_get_cb;
- this->unregister_put_cb = fifo_unregister_put_cb;
+ this->first = NULL;
+ this->last = NULL;
+ this->fifo_size = 0;
+ this->put = fifo_buffer_put;
+ this->insert = fifo_buffer_insert;
+ this->get = fifo_buffer_get;
+ this->clear = fifo_buffer_clear;
+ this->size = fifo_buffer_size;
+ this->num_free = fifo_buffer_num_free;
+ this->data_size = fifo_buffer_data_size;
+ this->dispose = fifo_buffer_dispose;
+ this->register_alloc_cb = fifo_register_alloc_cb;
+ this->register_get_cb = fifo_register_get_cb;
+ this->register_put_cb = fifo_register_put_cb;
+ this->unregister_alloc_cb = fifo_unregister_alloc_cb;
+ this->unregister_get_cb = fifo_unregister_get_cb;
+ this->unregister_put_cb = fifo_unregister_put_cb;
pthread_mutex_init (&this->mutex, NULL);
pthread_cond_init (&this->not_empty, NULL);
@@ -486,8 +530,10 @@ fifo_buffer_t *fifo_buffer_new (int num_buffers, uint32_t buf_size) {
buffer_pool_free (buf);
}
+ this->alloc_cb[0] = NULL;
this->get_cb[0] = NULL;
this->put_cb[0] = NULL;
+ this->alloc_cb_data[0] = NULL;
this->get_cb_data[0] = NULL;
this->put_cb_data[0] = NULL;
return this;
diff --git a/src/xine-engine/buffer.h b/src/xine-engine/buffer.h
index da2afa28f..abe3457b7 100644
--- a/src/xine-engine/buffer.h
+++ b/src/xine-engine/buffer.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: buffer.h,v 1.120 2003/08/05 15:20:00 mroi Exp $
+ * $Id: buffer.h,v 1.121 2003/10/14 22:16:32 tmattern Exp $
*
*
* contents:
@@ -467,8 +467,11 @@ struct fifo_buffer_s
/* the same as put but insert at the head of the fifo */
void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf);
+ /* callbacks */
+ void (*register_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *), void *cb_data);
void (*register_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data);
void (*register_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data);
+ void (*unregister_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *));
void (*unregister_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *));
void (*unregister_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *));
@@ -479,11 +482,13 @@ struct fifo_buffer_s
pthread_mutex_t buffer_pool_mutex;
pthread_cond_t buffer_pool_cond_not_empty;
int buffer_pool_num_free;
- int buffer_pool_capacity;
- int buffer_pool_buf_size;
+ int buffer_pool_capacity;
+ int buffer_pool_buf_size;
void *buffer_pool_base; /*used to free mem chunk */
+ void (*alloc_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, void *data_cb);
void (*put_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb);
void (*get_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb);
+ void *alloc_cb_data[BUF_MAX_CALLBACKS];
void *put_cb_data[BUF_MAX_CALLBACKS];
void *get_cb_data[BUF_MAX_CALLBACKS];
} ;