From 17979ae99228dd0422c26e366d6453663b9664a4 Mon Sep 17 00:00:00 2001 From: iovar Date: Mon, 29 Jan 2007 21:15:32 +0000 Subject: Fixed all condition variables, to be waited with correct mutexes. This fixed also the wakeup from pause bug. git-svn-id: https://recordmydesktop.svn.sourceforge.net/svnroot/recordmydesktop/trunk@269 f606c939-3180-4ac9-a4b8-4b8779d57d0a --- recordmydesktop/include/recordmydesktop.h | 1 + recordmydesktop/include/rmdtypes.h | 4 ++++ recordmydesktop/src/cache_audio.c | 13 +++++++------ recordmydesktop/src/cache_frame.c | 16 ++++++++++------ recordmydesktop/src/capture_sound.c | 18 +++++++++++------- recordmydesktop/src/encode_image_buffer.c | 18 +++++++++++------- recordmydesktop/src/encode_sound_buffer.c | 15 +++++++++------ recordmydesktop/src/flush_to_ogg.c | 13 ++++++++----- recordmydesktop/src/get_frame.c | 16 ++++++++++------ recordmydesktop/src/initialize_data.c | 7 ++++++- recordmydesktop/src/load_cache.c | 4 ++++ recordmydesktop/src/register_callbacks.c | 19 ++++++------------- recordmydesktop/src/rmdthreads.c | 4 ++++ 13 files changed, 91 insertions(+), 57 deletions(-) diff --git a/recordmydesktop/include/recordmydesktop.h b/recordmydesktop/include/recordmydesktop.h index e97a8c0..bd6e974 100644 --- a/recordmydesktop/include/recordmydesktop.h +++ b/recordmydesktop/include/recordmydesktop.h @@ -43,6 +43,7 @@ int Paused,*Running,Aborted; pthread_cond_t *time_cond,*pause_cond; +pthread_mutex_t pause_mutex,time_mutex; unsigned char Yr[256],Yg[256],Yb[256], Ur[256],Ug[256],Ub[256], Vr[256],Vg[256],Vb[256]; diff --git a/recordmydesktop/include/rmdtypes.h b/recordmydesktop/include/rmdtypes.h index de9565a..c97216d 100644 --- a/recordmydesktop/include/rmdtypes.h +++ b/recordmydesktop/include/rmdtypes.h @@ -273,6 +273,10 @@ typedef struct _ProgData{ pthread_mutex_t list_mutex[2], //mutexes for concurrency //protection of the lists sound_buffer_mutex, + snd_buff_ready_mutex, + img_buff_ready_mutex, + theora_lib_mutex, + vorbis_lib_mutex, libogg_mutex, //libogg is not thread safe, yuv_mutex; //this might not be needed since we only have //one read-only and one write-only thread diff --git a/recordmydesktop/src/cache_audio.c b/recordmydesktop/src/cache_audio.c index 178bb7c..edcabb3 100644 --- a/recordmydesktop/src/cache_audio.c +++ b/recordmydesktop/src/cache_audio.c @@ -34,19 +34,20 @@ void *CacheSoundBuffer(ProgData *pdata){ int framesize=((snd_pcm_format_width(SND_PCM_FORMAT_S16_LE))/8)* pdata->args.channels; #endif - pthread_mutex_t smut; - pthread_mutex_init(&smut,NULL); while((pdata->running)){ SndBuffer *buff; if(Paused){ - pthread_mutex_t tmut; - pthread_mutex_init(&tmut,NULL); - pthread_cond_wait(&pdata->pause_cond,&tmut); + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); } if(pdata->sound_buffer==NULL){ pdata->v_enc_thread_waiting=1; - pthread_cond_wait(&pdata->sound_data_read,&smut); + pthread_mutex_lock(&pdata->snd_buff_ready_mutex); + pthread_cond_wait(&pdata->sound_data_read, + &pdata->snd_buff_ready_mutex); + pthread_mutex_unlock(&pdata->snd_buff_ready_mutex); pdata->v_enc_thread_waiting=0; } if(pdata->sound_buffer==NULL || !pdata->running) diff --git a/recordmydesktop/src/cache_frame.c b/recordmydesktop/src/cache_frame.c index d57ecfd..6eb169a 100644 --- a/recordmydesktop/src/cache_frame.c +++ b/recordmydesktop/src/cache_frame.c @@ -96,9 +96,6 @@ int FlushBlock(unsigned char *buf, } void *CacheImageBuffer(ProgData *pdata){ - pthread_mutex_t pmut,imut; - pthread_mutex_init(&pmut,NULL); - pthread_mutex_init(&imut,NULL); yuv_buffer yuv[2]; gzFile *fp=NULL; FILE *ucfp=NULL; @@ -144,11 +141,18 @@ void *CacheImageBuffer(ProgData *pdata){ ynum=unum=vnum=0; pdata->th_enc_thread_waiting=1; - pthread_cond_wait(&pdata->image_buffer_ready,&imut); + pthread_mutex_lock(&pdata->img_buff_ready_mutex); + pthread_cond_wait(&pdata->image_buffer_ready, + &pdata->img_buff_ready_mutex); + pthread_mutex_unlock(&pdata->img_buff_ready_mutex); pdata->th_enc_thread_waiting=0; - if(Paused) - pthread_cond_wait(&pdata->pause_cond,&pmut); + if(Paused){ + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); + } + pthread_mutex_lock(&pdata->yuv_mutex); //rotate buffers diff --git a/recordmydesktop/src/capture_sound.c b/recordmydesktop/src/capture_sound.c index d9bb340..d9ffa91 100644 --- a/recordmydesktop/src/capture_sound.c +++ b/recordmydesktop/src/capture_sound.c @@ -34,9 +34,6 @@ void *CaptureSound(ProgData *pdata){ int framesize=((snd_pcm_format_width(SND_PCM_FORMAT_S16_LE))/8)* pdata->args.channels; #endif - pthread_mutex_t pmut; - pthread_mutex_init(&pmut,NULL); - //start capturing only after first frame is taken usleep(pdata->frametime); @@ -47,13 +44,16 @@ void *CaptureSound(ProgData *pdata){ #ifdef HAVE_LIBASOUND if(!pdata->hard_pause){ snd_pcm_pause(pdata->sound_handle,1); - pthread_cond_wait(&pdata->pause_cond,&pmut); + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); snd_pcm_pause(pdata->sound_handle,0); } else{//device doesn't support pause(is this the norm?mine doesn't) snd_pcm_close(pdata->sound_handle); - pthread_cond_wait(&pdata->pause_cond,&pmut); - + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); pdata->sound_handle= OpenDev(pdata->args.device, &pdata->args.channels, @@ -73,7 +73,9 @@ void *CaptureSound(ProgData *pdata){ } #else close(pdata->sound_handle); - pthread_cond_wait(&pdata->pause_cond,&pmut); + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); pdata->sound_handle= OpenDev(pdata->args.device, pdata->args.channels, @@ -147,7 +149,9 @@ void *CaptureSound(ProgData *pdata){ //signal that there are data to be proccessed + pthread_mutex_lock(&pdata->snd_buff_ready_mutex); pthread_cond_signal(&pdata->sound_data_read); + pthread_mutex_unlock(&pdata->snd_buff_ready_mutex); } #ifdef HAVE_LIBASOUND snd_pcm_close(pdata->sound_handle); diff --git a/recordmydesktop/src/encode_image_buffer.c b/recordmydesktop/src/encode_image_buffer.c index 97a78ed..4f7376d 100644 --- a/recordmydesktop/src/encode_image_buffer.c +++ b/recordmydesktop/src/encode_image_buffer.c @@ -26,18 +26,20 @@ #include void *EncodeImageBuffer(ProgData *pdata){ - pthread_mutex_t pmut,imut; - pthread_mutex_init(&pmut,NULL); - pthread_mutex_init(&imut,NULL); pdata->th_encoding_clean=0; while(pdata->running){ pdata->th_enc_thread_waiting=1; - pthread_cond_wait(&pdata->image_buffer_ready,&imut); + pthread_mutex_lock(&pdata->img_buff_ready_mutex); + pthread_cond_wait(&pdata->image_buffer_ready, + &pdata->img_buff_ready_mutex); + pthread_mutex_unlock(&pdata->img_buff_ready_mutex); pdata->th_enc_thread_waiting=0; encoder_busy=1; - if(Paused) - pthread_cond_wait(&pdata->pause_cond,&pmut);//this may - //not be needed + if(Paused){ + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); + } pthread_mutex_lock(&pdata->yuv_mutex); if(theora_encode_YUVin(&pdata->enc_data->m_th_st, @@ -60,7 +62,9 @@ void *EncodeImageBuffer(ProgData *pdata){ } //last packet pdata->th_encoding_clean=1; + pthread_mutex_lock(&pdata->theora_lib_mutex); pthread_cond_signal(&pdata->theora_lib_clean); + pthread_mutex_unlock(&pdata->theora_lib_mutex); pthread_exit(&errno); } diff --git a/recordmydesktop/src/encode_sound_buffer.c b/recordmydesktop/src/encode_sound_buffer.c index 2ea76cc..f20d98e 100644 --- a/recordmydesktop/src/encode_sound_buffer.c +++ b/recordmydesktop/src/encode_sound_buffer.c @@ -33,8 +33,6 @@ void *EncodeSoundBuffer(ProgData *pdata){ #else int sampread=pdata->args.buffsize>>1; #endif - pthread_mutex_t smut; - pthread_mutex_init(&smut,NULL); pdata->v_encoding_clean=0; while((pdata->running)){ float **vorbis_buffer; @@ -42,14 +40,17 @@ void *EncodeSoundBuffer(ProgData *pdata){ SndBuffer *buff; if(Paused){ - pthread_mutex_t tmut; - pthread_mutex_init(&tmut,NULL); - pthread_cond_wait(&pdata->pause_cond,&tmut); + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); } if(pdata->sound_buffer==NULL){ pdata->v_enc_thread_waiting=1; - pthread_cond_wait(&pdata->sound_data_read,&smut); + pthread_mutex_lock(&pdata->snd_buff_ready_mutex); + pthread_cond_wait(&pdata->sound_data_read, + &pdata->snd_buff_ready_mutex); + pthread_mutex_unlock(&pdata->snd_buff_ready_mutex); pdata->v_enc_thread_waiting=0; } if(pdata->sound_buffer==NULL || !pdata->running) @@ -93,7 +94,9 @@ void *EncodeSoundBuffer(ProgData *pdata){ } pdata->v_encoding_clean=1; + pthread_mutex_lock(&pdata->vorbis_lib_mutex); pthread_cond_signal(&pdata->vorbis_lib_clean); + pthread_mutex_unlock(&pdata->vorbis_lib_mutex); pthread_exit(&errno); } diff --git a/recordmydesktop/src/flush_to_ogg.c b/recordmydesktop/src/flush_to_ogg.c index cc00708..b8d1625 100644 --- a/recordmydesktop/src/flush_to_ogg.c +++ b/recordmydesktop/src/flush_to_ogg.c @@ -66,9 +66,6 @@ void *FlushToOgg(ProgData *pdata){ double audiotime=0; double videotime=0; - pthread_mutex_t imut,vmut; - pthread_mutex_init(&imut,NULL); - pthread_mutex_init(&vmut,NULL); int working=1, th_st_fin=0, v_st_fin=(pdata->args.nosound); @@ -108,7 +105,10 @@ void *FlushToOgg(ProgData *pdata){ //we need the last page to properly close the stream if(!videoflag){ if(!pdata->th_encoding_clean){ - pthread_cond_wait(&pdata->theora_lib_clean,&imut); + pthread_mutex_lock(&pdata->theora_lib_mutex); + pthread_cond_wait(&pdata->theora_lib_clean, + &pdata->theora_lib_mutex); + pthread_mutex_unlock(&pdata->theora_lib_mutex); } SyncEncodeImageBuffer(pdata); } @@ -125,7 +125,10 @@ void *FlushToOgg(ProgData *pdata){ //we need the last page to properly close the stream if(!audioflag){ if(!pdata->v_encoding_clean){ - pthread_cond_wait(&pdata->vorbis_lib_clean,&vmut); + pthread_mutex_lock(&pdata->vorbis_lib_mutex); + pthread_cond_wait(&pdata->vorbis_lib_clean, + &pdata->vorbis_lib_mutex); + pthread_mutex_unlock(&pdata->vorbis_lib_mutex); } SyncEncodeSoundBuffer(pdata,NULL); } diff --git a/recordmydesktop/src/get_frame.c b/recordmydesktop/src/get_frame.c index 425049b..31dba8d 100644 --- a/recordmydesktop/src/get_frame.c +++ b/recordmydesktop/src/get_frame.c @@ -31,7 +31,6 @@ void *GetFrame(ProgData *pdata){ int tlist_sel=0; unsigned char *dtap=NULL; //pointer switching among shared memory and //normal buffer - pthread_mutex_t pmut,tmut; uint msk_ret; WGeometry mouse_pos_abs,mouse_pos_rel,mouse_pos_temp; Window root_ret,child_ret; @@ -42,8 +41,6 @@ void *GetFrame(ProgData *pdata){ mouse_pos_abs.y=mouse_pos_temp.y=0; mouse_pos_abs.width=mouse_pos_temp.width=pdata->dummy_p_size; mouse_pos_abs.height=mouse_pos_temp.height=pdata->dummy_p_size; - pthread_mutex_init(&pmut,NULL); - pthread_mutex_init(&tmut,NULL); while(pdata->running){ @@ -51,14 +48,17 @@ void *GetFrame(ProgData *pdata){ //also before actually pausing we must make sure the streams //are synced. sound stops so this should only happen quickly. if(pdata->avd>0){ - pthread_cond_wait(&pdata->time_cond,&tmut); + pthread_mutex_lock(&time_mutex); + pthread_cond_wait(&pdata->time_cond,&time_mutex); + pthread_mutex_unlock(&time_mutex); if(Paused){ - pthread_cond_wait(&pdata->pause_cond,&pmut); + pthread_mutex_lock(&pause_mutex); + pthread_cond_wait(&pdata->pause_cond,&pause_mutex); + pthread_mutex_unlock(&pause_mutex); } } capture_busy=1; - /*pthread_cond_wait(&pdata->pause_cond,&pdata->pause_cond_mutex);*/ //mutexes and lists with changes are useless when full_shots is enabled if(!pdata->args.full_shots){ tlist_sel=pdata->list_selector; @@ -215,10 +215,14 @@ void *GetFrame(ProgData *pdata){ if(encoder_busy){ frames_lost++; } + pthread_mutex_lock(&pdata->img_buff_ready_mutex); pthread_cond_broadcast(&pdata->image_buffer_ready); + pthread_mutex_unlock(&pdata->img_buff_ready_mutex); capture_busy=0; } + pthread_mutex_lock(&pdata->img_buff_ready_mutex); pthread_cond_broadcast(&pdata->image_buffer_ready); + pthread_mutex_unlock(&pdata->img_buff_ready_mutex); pthread_exit(&errno); } diff --git a/recordmydesktop/src/initialize_data.c b/recordmydesktop/src/initialize_data.c index 8d86856..4df3a6f 100644 --- a/recordmydesktop/src/initialize_data.c +++ b/recordmydesktop/src/initialize_data.c @@ -55,9 +55,14 @@ int InitializeData(ProgData *pdata, pthread_mutex_init(&pdata->list_mutex[0],NULL); pthread_mutex_init(&pdata->list_mutex[1],NULL); pthread_mutex_init(&pdata->sound_buffer_mutex,NULL); + pthread_mutex_init(&pdata->snd_buff_ready_mutex,NULL); + pthread_mutex_init(&pdata->img_buff_ready_mutex,NULL); + pthread_mutex_init(&pdata->theora_lib_mutex,NULL); + pthread_mutex_init(&pdata->vorbis_lib_mutex,NULL); pthread_mutex_init(&pdata->libogg_mutex,NULL); pthread_mutex_init(&pdata->yuv_mutex,NULL); - + pthread_mutex_init(&pause_mutex,NULL); + pthread_mutex_init(&time_mutex,NULL); pthread_cond_init(&pdata->time_cond,NULL); pthread_cond_init(&pdata->pause_cond,NULL); pthread_cond_init(&pdata->image_buffer_ready,NULL); diff --git a/recordmydesktop/src/load_cache.c b/recordmydesktop/src/load_cache.c index a5b1581..00ddf96 100644 --- a/recordmydesktop/src/load_cache.c +++ b/recordmydesktop/src/load_cache.c @@ -268,8 +268,12 @@ void *LoadCache(ProgData *pdata){ } pdata->v_encoding_clean=pdata->th_encoding_clean=1; + pthread_mutex_lock(&pdata->theora_lib_mutex); pthread_cond_signal(&pdata->theora_lib_clean); + pthread_mutex_unlock(&pdata->theora_lib_mutex); + pthread_mutex_lock(&pdata->vorbis_lib_mutex); pthread_cond_signal(&pdata->vorbis_lib_clean); + pthread_mutex_unlock(&pdata->vorbis_lib_mutex); fprintf(stdout,"\n"); CLEAR_FRAME(&frame) free(sound_data); diff --git a/recordmydesktop/src/register_callbacks.c b/recordmydesktop/src/register_callbacks.c index 27244fe..7f8d04f 100644 --- a/recordmydesktop/src/register_callbacks.c +++ b/recordmydesktop/src/register_callbacks.c @@ -32,6 +32,7 @@ void SetExpired(int signum){ if(capture_busy){ frames_lost++; } + pthread_mutex_lock(&time_mutex); pthread_cond_broadcast(time_cond); //sig handlers should //not call this func //could be a set_expired @@ -39,6 +40,7 @@ void SetExpired(int signum){ //doing a while(running) //if set_expired broadcast //else usleep(n) + pthread_mutex_unlock(&time_mutex); } } @@ -46,19 +48,10 @@ void SetPaused(int signum){ if(!Paused) Paused=1; else{ -// pthread_cond_broadcast(pause_cond);//this should work, -// but it doesn't - int i; //this is a bug - Paused=0; //normally with the broadcast - //all the threads should restart, - //but sound capture thread - for(i=0;i<15;i++) //remains dead. If a bunch of signals, - pthread_cond_signal(pause_cond);//restarts all threads, - //why can't a broadcast - //do the same? - //if you have any idea - //please contact me. - //(misses the signal?) + Paused=0; + pthread_mutex_lock(&pause_mutex); + pthread_cond_broadcast(pause_cond); + pthread_mutex_unlock(&pause_mutex); } } diff --git a/recordmydesktop/src/rmdthreads.c b/recordmydesktop/src/rmdthreads.c index 442c67e..4199472 100644 --- a/recordmydesktop/src/rmdthreads.c +++ b/recordmydesktop/src/rmdthreads.c @@ -96,7 +96,9 @@ void rmdThreads(ProgData *pdata){ //if no damage events have been received the thread will get stuck while(!pdata->th_enc_thread_waiting && !pdata->th_encoding_clean){ usleep(10000); + pthread_mutex_lock(&pdata->img_buff_ready_mutex); pthread_cond_signal(&pdata->image_buffer_ready); + pthread_mutex_unlock(&pdata->img_buff_ready_mutex); } if(pdata->args.encOnTheFly){ @@ -110,7 +112,9 @@ void rmdThreads(ProgData *pdata){ fprintf(stderr,"."); while(!pdata->v_enc_thread_waiting && !pdata->v_encoding_clean){ usleep(10000); + pthread_mutex_lock(&pdata->snd_buff_ready_mutex); pthread_cond_signal(&pdata->sound_data_read); + pthread_mutex_unlock(&pdata->snd_buff_ready_mutex); } if(pdata->args.encOnTheFly){ pthread_join(sound_encode_t,NULL); -- cgit v1.2.3