Commit 9117185f authored by Simon Morlat's avatar Simon Morlat

fix crash when destroying a filter that has events pending in the event queue

parent 9cd81464
......@@ -682,6 +682,7 @@ MS2_PUBLIC bool_t ms_filter_inputs_have_data(MSFilter *f);
MS2_PUBLIC void ms_filter_notify(MSFilter *f, unsigned int id, void *arg);
MS2_PUBLIC void ms_filter_notify_no_arg(MSFilter *f, unsigned int id);
void ms_filter_clear_notify_callback(MSFilter *f);
void ms_filter_clean_pending_events(MSFilter *f);
#define ms_filter_lock(f) ms_mutex_lock(&(f)->lock)
#define ms_filter_unlock(f) ms_mutex_unlock(&(f)->lock)
MS2_PUBLIC void ms_filter_unregister_all(void);
......
......@@ -77,6 +77,16 @@ static void write_event(MSEventQueue *q, MSFilter *f, unsigned int ev_id, void *
ms_mutex_unlock(&q->mutex);
}
static int parse_event(uint8_t *rptr,MSFilter **f, unsigned int *id, void **data, int *argsize){
int evsize;
*f=(MSFilter *)*(long*)(rptr);
*id=(unsigned int)*(long*)(rptr+8);
*argsize=(*id) & 0xff;
evsize=(*argsize)+16;
*data=rptr+16;
return evsize;
}
static bool_t read_event(MSEventQueue *q){
int available=q->size-q->freeroom;
if (available>0){
......@@ -86,12 +96,8 @@ static bool_t read_event(MSEventQueue *q){
int argsize;
int evsize;
f=(MSFilter *)*(long*)(q->rptr);
id=(unsigned int)*(long*)(q->rptr+8);
argsize=id & 0xff;
evsize=argsize+16;
data=q->rptr+16;
ms_filter_invoke_callbacks(f,id,argsize>0 ? data : NULL, OnlyAsynchronous);
evsize=parse_event(q->rptr,&f,&id,&data,&argsize);
if (f) ms_filter_invoke_callbacks(f,id,argsize>0 ? data : NULL, OnlyAsynchronous);
q->rptr+=evsize;
if (q->rptr>=q->endptr){
q->rptr=q->buffer;
......@@ -104,6 +110,32 @@ static bool_t read_event(MSEventQueue *q){
return FALSE;
}
/*clean all events belonging to a MSFilter that is about to be destroyed*/
void ms_event_queue_clean(MSEventQueue *q, MSFilter *destroyed){
int freeroom=q->freeroom;
uint8_t *rptr=q->rptr;
while(q->size>freeroom){
MSFilter *f;
unsigned int id;
void *data;
int argsize;
int evsize;
evsize=parse_event(rptr,&f,&id,&data,&argsize);
if (f==destroyed){
ms_message("Cleaning pending event of MSFilter [%s:%p]",destroyed->desc->name,destroyed);
*(long*)rptr=0;
}
rptr+=evsize;
if (rptr>=q->endptr){
rptr=q->buffer;
}
freeroom+=evsize;
}
}
MSEventQueue *ms_event_queue_new(){
MSEventQueue *q=ms_new0(MSEventQueue,1);
int bufsize=MS_EVENT_BUF_SIZE;
......@@ -210,4 +242,8 @@ void ms_filter_notify_no_arg(MSFilter *f, unsigned int id){
ms_filter_notify(f,id,NULL);
}
void ms_filter_clean_pending_events(MSFilter *f){
if (ms_global_event_queue)
ms_event_queue_clean(ms_global_event_queue,f);
}
......@@ -306,6 +306,7 @@ void ms_filter_destroy(MSFilter *f){
if (f->outputs!=NULL) ms_free(f->outputs);
ms_mutex_destroy(&f->lock);
ms_filter_clear_notify_callback(f);
ms_filter_clean_pending_events(f);
ms_free(f);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment