static void *msg_thread (void *data) { msg_subscription_t *sub = data; msg_bank_t *bank = libvlc_bank (sub->instance); vlc_mutex_lock (&bank->lock); for (;;) { /* Wait for messages */ assert (sub->begin < VLC_MSG_QSIZE); assert (sub->end < VLC_MSG_QSIZE); while (sub->begin != sub->end) { msg_item_t *msg = sub->items[sub->begin]; unsigned overruns = sub->overruns; if (++sub->begin == VLC_MSG_QSIZE) sub->begin = 0; sub->overruns = 0; vlc_mutex_unlock (&bank->lock); sub->func (sub->opaque, msg, overruns); msg_Release (msg); vlc_mutex_lock (&bank->lock); } mutex_cleanup_push (&bank->lock); vlc_cond_wait (&bank->wait, &bank->lock); vlc_cleanup_pop (); } assert (0); }
/***************************************************************************** * ALSAThread: asynchronous thread used to DMA the data to the device *****************************************************************************/ static void* ALSAThread( vlc_object_t* p_this ) { aout_instance_t * p_aout = (aout_instance_t*)p_this; struct aout_sys_t * p_sys = p_aout->output.p_sys; int canc = vlc_savecancel (); p_sys->p_status = (snd_pcm_status_t *)malloc(snd_pcm_status_sizeof()); /* Wait for the exact time to start playing (avoids resampling) */ vlc_mutex_lock( &p_sys->lock ); while( !p_sys->start_date && vlc_object_alive (p_aout) ) vlc_cond_wait( &p_sys->wait, &p_sys->lock ); vlc_mutex_unlock( &p_sys->lock ); if( !vlc_object_alive (p_aout) ) goto cleanup; mwait( p_sys->start_date - AOUT_PTS_TOLERANCE / 4 ); while ( vlc_object_alive (p_aout) ) { ALSAFill( p_aout ); } cleanup: snd_pcm_drop( p_sys->p_snd_pcm ); free( p_aout->output.p_sys->p_status ); vlc_restorecancel (canc); return NULL; }
void playlist_preparser_Delete( playlist_preparser_t *p_preparser ) { vlc_mutex_lock( &p_preparser->lock ); /* Remove pending item to speed up preparser thread exit */ while( p_preparser->i_waiting > 0 ) { preparser_entry_t *p_entry = p_preparser->pp_waiting[0]; vlc_gc_decref( p_entry->p_item ); free( p_entry ); REMOVE_ELEM( p_preparser->pp_waiting, p_preparser->i_waiting, 0 ); } vlc_sem_post( &p_preparser->item_done ); while( p_preparser->b_live ) vlc_cond_wait( &p_preparser->wait, &p_preparser->lock ); vlc_mutex_unlock( &p_preparser->lock ); /* Destroy the item preparser */ vlc_sem_destroy( &p_preparser->item_done ); vlc_cond_destroy( &p_preparser->wait ); vlc_mutex_destroy( &p_preparser->lock ); if( p_preparser->p_fetcher != NULL ) playlist_fetcher_Delete( p_preparser->p_fetcher ); free( p_preparser ); }
picture_t *picture_pool_Wait(picture_pool_t *pool) { unsigned i; vlc_mutex_lock(&pool->lock); assert(pool->refs > 0); while (pool->available == 0) vlc_cond_wait(&pool->wait, &pool->lock); i = ffsll(pool->available); assert(i > 0); pool->available &= ~(1ULL << (i - 1)); vlc_mutex_unlock(&pool->lock); picture_t *picture = pool->picture[i - 1]; if (pool->pic_lock != NULL && pool->pic_lock(picture) != 0) { vlc_mutex_lock(&pool->lock); pool->available |= 1ULL << (i - 1); vlc_cond_signal(&pool->wait); vlc_mutex_unlock(&pool->lock); return NULL; } picture_t *clone = picture_pool_ClonePicture(pool, i - 1); if (clone != NULL) { assert(clone->p_next == NULL); atomic_fetch_add(&pool->refs, 1); } return clone; }
/************************************************************************** * event_async_loop (private) : * * Send queued events. **************************************************************************/ static void * event_async_loop(void * arg) { libvlc_event_manager_t * p_em = arg; libvlc_event_listener_t listener; libvlc_event_t event; vlc_threadvar_set(queue(p_em)->is_asynch_dispatch_thread_var, p_em); queue_lock(p_em); while (true) { int has_listener = pop(p_em, &listener, &event); if (has_listener) { queue_unlock(p_em); listener.pf_callback(&event, listener.p_user_data); // This might edit the queue queue_lock(p_em); } else { queue(p_em)->is_idle = true; mutex_cleanup_push(&queue(p_em)->lock); vlc_cond_broadcast(&queue(p_em)->signal_idle); // We'll be idle vlc_cond_wait(&queue(p_em)->signal, &queue(p_em)->lock); vlc_cleanup_pop(); queue(p_em)->is_idle = false; } } queue_unlock(p_em); return NULL; }
static void flush(filter_t *filter) { filter_sys_t *sys = filter->p_sys; MMAL_BUFFER_HEADER_T *buffer; msg_Dbg(filter, "flush deinterlace filter"); if (atomic_load(&sys->input_in_transit) || atomic_load(&sys->output_in_transit)) { msg_Dbg(filter, "flush: flush ports (input: %d, output: %d in transit)", sys->input_in_transit, sys->output_in_transit); mmal_port_flush(sys->output); mmal_port_flush(sys->input); msg_Dbg(filter, "flush: wait for all buffers to be returned"); vlc_mutex_lock(&sys->buffer_cond_mutex); while (atomic_load(&sys->input_in_transit) || atomic_load(&sys->output_in_transit)) { vlc_cond_wait(&sys->buffer_cond, &sys->buffer_cond_mutex); } vlc_mutex_unlock(&sys->buffer_cond_mutex); } while ((buffer = mmal_queue_get(sys->filtered_pictures))) { picture_t *pic = (picture_t *)buffer->user_data; msg_Dbg(filter, "flush: release already filtered pic %p", (void *)pic); picture_Release(pic); } msg_Dbg(filter, "flush: done"); }
static int FfmpegThread( struct thread_context_t *p_context ) { while ( !p_context->b_die && !p_context->b_error ) { vlc_mutex_lock( &p_context->lock ); while ( !p_context->b_work && !p_context->b_die && !p_context->b_error ) { vlc_cond_wait( &p_context->cond, &p_context->lock ); } p_context->b_work = 0; vlc_mutex_unlock( &p_context->lock ); if ( p_context->b_die || p_context->b_error ) break; if ( p_context->pf_func ) { p_context->i_ret = p_context->pf_func( p_context->p_context, p_context->arg ); } vlc_mutex_lock( &p_context->lock ); p_context->b_done = 1; vlc_cond_signal( &p_context->cond ); vlc_mutex_unlock( &p_context->lock ); } return 0; }
static int EcoreMainLoopCallSync( vout_display_t *vd, mainloop_cb p_cb ) { vout_display_sys_t *sys = vd->sys; struct mainloop_cb_args args = { .vd = vd, .p_cb = p_cb, .b_signal = false }; ecore_main_loop_thread_safe_call_async( EcoreMainLoopCb, &args ); vlc_mutex_lock( &sys->cb_lock ); while( !args.b_signal ) vlc_cond_wait( &sys->cb_wait, &sys->cb_lock ); vlc_mutex_unlock( &sys->cb_lock ); return args.i_ret; } #ifdef HAVE_EVAS_CALLBACK_KEY_UP static void EventSendKey( vout_display_t *vd, int i_key ) { vout_display_sys_t *sys = vd->sys; struct event *p_event = malloc( sizeof(struct event) ); if( !p_event ) return; p_event->i_type = VOUT_DISPLAY_EVENT_KEY; p_event->u.i_key = i_key; EVENT_FIFO_PUSH( p_event ); }
static int dialog_wait(vlc_dialog_provider *p_provider, vlc_dialog_id *p_id, enum dialog_type i_type, struct dialog_answer *p_answer) { struct dialog_i11e_context context = { .p_provider = p_provider, .p_id = p_id, }; vlc_interrupt_register(dialog_wait_interrupted, &context); vlc_mutex_lock(&p_id->lock); /* Wait for the dialog to be dismissed, interrupted or answered */ while (!p_id->b_cancelled && !p_id->b_answered) vlc_cond_wait(&p_id->wait, &p_id->lock); int i_ret; if (p_id->b_cancelled) i_ret = 0; else if (p_id->answer.i_type != i_type) i_ret = VLC_EGENERIC; else { i_ret = 1; memcpy(p_answer, &p_id->answer, sizeof(p_id->answer)); memset(&p_id->answer, 0, sizeof(p_id->answer)); } vlc_mutex_unlock(&p_id->lock); vlc_interrupt_unregister(); vlc_mutex_lock(&p_provider->lock); dialog_remove_locked(p_provider, p_id); vlc_mutex_unlock(&p_provider->lock); return i_ret; }
/** * main SAP handler thread * \param p_this the SAP Handler object * \return nothing */ static void *RunThread (void *self) { sap_address_t *addr = self; vlc_mutex_lock (&addr->lock); mutex_cleanup_push (&addr->lock); for (;;) { sap_session_t *p_session; mtime_t deadline; while (addr->first == NULL) vlc_cond_wait (&addr->wait, &addr->lock); assert (addr->session_count > 0); deadline = mdate (); for (p_session = addr->first; p_session; p_session = p_session->next) { send (addr->fd, p_session->data, p_session->length, 0); deadline += addr->interval * CLOCK_FREQ / addr->session_count; if (vlc_cond_timedwait (&addr->wait, &addr->lock, deadline) == 0) break; /* list may have changed! */ } } vlc_cleanup_pop (); assert (0); }
/** * Run the main control thread itself */ static void *Thread ( void *data ) { playlist_t *p_playlist = data; playlist_private_t *p_sys = pl_priv(p_playlist); playlist_Lock( p_playlist ); while( vlc_object_alive( p_playlist ) || p_sys->p_input ) { /* FIXME: what's that ! */ if( p_sys->b_reset_currently_playing && mdate() - p_sys->last_rebuild_date > 30000 ) // 30 ms { ResetCurrentlyPlaying( p_playlist, get_current_status_item( p_playlist ) ); p_sys->last_rebuild_date = mdate(); } /* If there is an input, check that it doesn't need to die. */ while( !LoopInput( p_playlist ) ) vlc_cond_wait( &p_sys->signal, &p_sys->lock ); LoopRequest( p_playlist ); } playlist_Unlock( p_playlist ); return NULL; }
static void BackgroundWorkerCancel( struct background_worker* worker, void* id) { vlc_mutex_lock( &worker->lock ); for( size_t i = 0; i < vlc_array_count( &worker->tail.data ); ) { struct bg_queued_item* item = vlc_array_item_at_index( &worker->tail.data, i ); if( id == NULL || item->id == id ) { vlc_array_remove( &worker->tail.data, i ); worker->conf.pf_release( item->entity ); free( item ); continue; } ++i; } while( ( id == NULL && worker->head.active ) || ( id != NULL && worker->head.id == id ) ) { worker->head.deadline = VLC_TS_0; vlc_cond_signal( &worker->head.worker_wait ); vlc_cond_signal( &worker->tail.wait ); vlc_cond_wait( &worker->head.wait, &worker->lock ); } vlc_mutex_unlock( &worker->lock ); }
/***************************************************************************** * Thread: *****************************************************************************/ static void *Thread( void *p_thread_data ) { goom_thread_t *p_thread = (goom_thread_t*)p_thread_data; date_t i_pts; int16_t p_data[2][512]; int i_data = 0, i_count = 0; PluginInfo *p_plugin_info; int canc = vlc_savecancel (); p_plugin_info = goom_init( p_thread->i_width, p_thread->i_height ); for( ;; ) { uint32_t *plane; picture_t *p_pic; /* FIXME the way the update is done is not really good. * Supurious wake up from p_thread->wait will make it generates a frame * without using new samples (probably rare as we should not be waiting * samples). * The frame rate at which the video is generated is not well controlled * nor the time at which each frame is displayed (not smooth) */ /* goom_update is damn slow, so just copy data and release the lock */ vlc_mutex_lock( &p_thread->lock ); if( !p_thread->b_exit && FillBuffer( (int16_t *)p_data, &i_data, &i_pts, &p_thread->date, p_thread ) != VLC_SUCCESS ) vlc_cond_wait( &p_thread->wait, &p_thread->lock ); bool b_exit = p_thread->b_exit; vlc_mutex_unlock( &p_thread->lock ); if( b_exit ) break; /* Speed selection */ if( p_thread->i_speed && (++i_count % (p_thread->i_speed+1)) ) continue; /* Frame dropping if necessary */ if( date_Get( &i_pts ) + GOOM_DELAY <= mdate() ) continue; plane = goom_update( p_plugin_info, p_data, 0, 0.0, NULL, NULL ); p_pic = vout_GetPicture( p_thread->p_vout ); if( unlikely(p_pic == NULL) ) continue; memcpy( p_pic->p[0].p_pixels, plane, p_thread->i_width * p_thread->i_height * 4 ); p_pic->date = date_Get( &i_pts ) + GOOM_DELAY; vout_PutPicture( p_thread->p_vout, p_pic ); } goom_close( p_plugin_info ); vlc_restorecancel (canc); return NULL; }
/** * Waits until the variable is inactive (i.e. not executing a callback) */ static void WaitUnused(vlc_object_t *obj, variable_t *var) { vlc_object_internals_t *priv = vlc_internals(obj); mutex_cleanup_push(&priv->var_lock); while (var->b_incallback) vlc_cond_wait(&priv->var_wait, &priv->var_lock); vlc_cleanup_pop(); }
/***************************************************************************** * Run: Thread entry-point ****************************************************************************/ static void* Run( void *data ) { services_discovery_t *p_sd = ( services_discovery_t * )data; services_discovery_sys_t *p_sys = p_sd->p_sys; lua_State *L = p_sys->L; int cancel = vlc_savecancel(); lua_getglobal( L, "main" ); if( !lua_isfunction( L, lua_gettop( L ) ) || lua_pcall( L, 0, 1, 0 ) ) { msg_Err( p_sd, "Error while running script %s, " "function main(): %s", p_sys->psz_filename, lua_tostring( L, lua_gettop( L ) ) ); lua_pop( L, 1 ); vlc_restorecancel( cancel ); return NULL; } msg_Dbg( p_sd, "LuaSD script loaded: %s", p_sys->psz_filename ); /* Force garbage collection, because the core will keep the SD * open, but lua will never gc until lua_close(). */ lua_gc( L, LUA_GCCOLLECT, 0 ); vlc_restorecancel( cancel ); /* Main loop to handle search requests */ vlc_mutex_lock( &p_sys->lock ); mutex_cleanup_push( &p_sys->lock ); while( !p_sys->b_exiting ) { /* Wait for a request */ while( !p_sys->i_query ) vlc_cond_wait( &p_sys->cond, &p_sys->lock ); /* Execute every query each one protected against cancelation */ cancel = vlc_savecancel(); while( !p_sys->b_exiting && p_sys->i_query ) { char *psz_query = p_sys->ppsz_query[p_sys->i_query - 1]; REMOVE_ELEM( (char **), p_sys->ppsz_query, p_sys->i_query, p_sys->i_query - 1 ); // sunqueen modify vlc_mutex_unlock( &p_sys->lock ); DoSearch( p_sd, psz_query ); free( psz_query ); vlc_mutex_lock( &p_sys->lock ); } /* Force garbage collection, because the core will keep the SD * open, but lua will never gc until lua_close(). */ lua_gc( L, LUA_GCCOLLECT, 0 ); vlc_restorecancel( cancel ); } vlc_cleanup_run(); return NULL; }
/************************************************************************** * Parse the media. **************************************************************************/ void libvlc_media_parse(libvlc_media_t *media) { preparse_if_needed(media); vlc_mutex_lock(&media->parsed_lock); while (!media->is_parsed) vlc_cond_wait(&media->parsed_cond, &media->parsed_lock); vlc_mutex_unlock(&media->parsed_lock); }
void vlc_rwlock_wrlock (vlc_rwlock_t *lock) { vlc_mutex_lock (&lock->mutex); /* Wait until nobody owns the lock in either way. */ while ((lock->readers > 0) || (lock->writer != 0)) vlc_cond_wait (&lock->wait, &lock->mutex); assert (lock->writer == 0); lock->writer = GetCurrentThreadId (); vlc_mutex_unlock (&lock->mutex); }
static void LoopRequest( playlist_t *p_playlist ) { playlist_private_t *p_sys = pl_priv(p_playlist); assert( !p_sys->p_input ); /* No input. Several cases * - No request, running status -> start new item * - No request, stopped status -> collect garbage * - Request, running requested -> start new item * - Request, stopped requested -> collect garbage */ const int i_status = p_sys->request.b_request ? p_sys->request.i_status : p_sys->status.i_status; if( i_status == PLAYLIST_STOPPED || !vlc_object_alive( p_playlist ) ) { p_sys->status.i_status = PLAYLIST_STOPPED; if( p_sys->p_input_resource && input_resource_HasVout( p_sys->p_input_resource ) ) { /* XXX We can unlock if we don't issue the wait as we will be * call again without anything else done between the calls */ PL_UNLOCK; /* input_resource_t must be manipulated without playlist lock */ input_resource_TerminateVout( p_sys->p_input_resource ); PL_LOCK; } else { if( vlc_object_alive( p_playlist ) ) vlc_cond_wait( &p_sys->signal, &p_sys->lock ); } return; } playlist_item_t *p_item = NextItem( p_playlist ); if( p_item ) { msg_Dbg( p_playlist, "starting playback of the new playlist item" ); PlayItem( p_playlist, p_item ); return; } msg_Dbg( p_playlist, "nothing to play" ); p_sys->status.i_status = PLAYLIST_STOPPED; if( var_GetBool( p_playlist, "play-and-exit" ) ) { msg_Info( p_playlist, "end of playlist, exiting" ); libvlc_Quit( p_playlist->p_libvlc ); } }
/** * Receives stream data. * * Dequeues pending incoming data for an HTTP/2 stream. If there is currently * no data block, wait for one. * * \return a VLC data block, or NULL on stream error or end of stream */ static block_t *vlc_h2_stream_read(struct vlc_http_stream *stream) { struct vlc_h2_stream *s = (struct vlc_h2_stream *)stream; struct vlc_h2_conn *conn = s->conn; struct vlc_h2_frame *f; vlc_h2_stream_lock(s); while ((f = s->recv_head) == NULL && !s->recv_end && !s->interrupted) { mutex_cleanup_push(&conn->lock); vlc_cond_wait(&s->recv_wait, &conn->lock); vlc_cleanup_pop(); } if (f == NULL) { vlc_h2_stream_unlock(s); return NULL; } s->recv_head = f->next; if (f->next == NULL) { assert(s->recv_tailp == &f->next); s->recv_tailp = &s->recv_head; } /* Credit the receive window if missing credit exceeds 50%. */ uint_fast32_t credit = VLC_H2_INIT_WINDOW - s->recv_cwnd; if (credit >= (VLC_H2_INIT_WINDOW / 2) && !vlc_h2_output_send(conn->out, vlc_h2_frame_window_update(s->id, credit))) s->recv_cwnd += credit; vlc_h2_stream_unlock(s); /* This, err, unconventional code to avoid copying data. */ block_t *block = block_heap_Alloc(f, sizeof (*f) + vlc_h2_frame_size(f)); if (unlikely(block == NULL)) { free(f); vlc_h2_stream_error(conn, s->id, VLC_H2_INTERNAL_ERROR); return NULL; } size_t len; uint8_t *buf = vlc_h2_frame_data_get(f, &len); assert(block->i_buffer >= len); assert(block->p_buffer <= buf); assert(block->p_buffer + block->i_buffer >= buf + len); block->p_buffer = buf; block->i_buffer = len; return block; }
/** * Destroys an initialized timer. If needed, the timer is first disarmed. * This function is undefined if the specified timer is not initialized. * * @warning This function <b>must</b> be called before the timer data can be * freed and before the timer callback function can be unloaded. * * @param timer timer to destroy */ void vlc_timer_destroy (vlc_timer_t timer) { vlc_timer_schedule (timer, false, 0, 0); vlc_mutex_lock (&timer->lock); while (timer->users != 0) vlc_cond_wait (&timer->wait, &timer->lock); vlc_mutex_unlock (&timer->lock); vlc_cond_destroy (&timer->wait); vlc_mutex_destroy (&timer->lock); free (timer); }
static void* EncoderThread( void *obj ) { sout_stream_sys_t *p_sys = (sout_stream_sys_t*)obj; sout_stream_id_sys_t *id = p_sys->id_video; picture_t *p_pic = NULL; int canc = vlc_savecancel (); block_t *p_block = NULL; vlc_mutex_lock( &p_sys->lock_out ); for( ;; ) { while( !p_sys->b_abort && (p_pic = picture_fifo_Pop( p_sys->pp_pics )) == NULL ) vlc_cond_wait( &p_sys->cond, &p_sys->lock_out ); if( p_pic ) { /* release lock while encoding */ vlc_mutex_unlock( &p_sys->lock_out ); p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic ); picture_Release( p_pic ); vlc_mutex_lock( &p_sys->lock_out ); block_ChainAppend( &p_sys->p_buffers, p_block ); } if( p_sys->b_abort ) break; } /*Encode what we have in the buffer on closing*/ while( (p_pic = picture_fifo_Pop( p_sys->pp_pics )) != NULL ) { p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic ); picture_Release( p_pic ); block_ChainAppend( &p_sys->p_buffers, p_block ); } /*Now flush encoder*/ do { p_block = id->p_encoder->pf_encode_video(id->p_encoder, NULL ); block_ChainAppend( &p_sys->p_buffers, p_block ); } while( p_block ); vlc_mutex_unlock( &p_sys->lock_out ); vlc_restorecancel (canc); return NULL; }
static void vd_display(vout_display_t *vd, picture_t *picture, subpicture_t *subpicture) { vout_display_sys_t *sys = vd->sys; picture_sys_t *pic_sys = picture->p_sys; MMAL_BUFFER_HEADER_T *buffer = pic_sys->buffer; MMAL_STATUS_T status; if (picture->format.i_frame_rate != sys->i_frame_rate || picture->format.i_frame_rate_base != sys->i_frame_rate_base || picture->b_progressive != sys->b_progressive || picture->b_top_field_first != sys->b_top_field_first) { sys->b_top_field_first = picture->b_top_field_first; sys->b_progressive = picture->b_progressive; sys->i_frame_rate = picture->format.i_frame_rate; sys->i_frame_rate_base = picture->format.i_frame_rate_base; configure_display(vd, NULL, &picture->format); } if (!pic_sys->displayed || !sys->opaque) { buffer->cmd = 0; buffer->length = sys->input->buffer_size; vlc_mutex_lock(&sys->buffer_mutex); while (sys->buffers_in_transit >= MAX_BUFFERS_IN_TRANSIT) vlc_cond_wait(&sys->buffer_cond, &sys->buffer_mutex); status = mmal_port_send_buffer(sys->input, buffer); if (status == MMAL_SUCCESS) ++sys->buffers_in_transit; vlc_mutex_unlock(&sys->buffer_mutex); if (status != MMAL_SUCCESS) { msg_Err(vd, "Failed to send buffer to input port. Frame dropped"); picture_Release(picture); } pic_sys->displayed = true; } else { picture_Release(picture); } display_subpicture(vd, subpicture); if (subpicture) subpicture_Delete(subpicture); if (sys->next_phase_check == 0 && sys->adjust_refresh_rate) maintain_phase_sync(vd); sys->next_phase_check = (sys->next_phase_check + 1) % PHASE_CHECK_INTERVAL; }
static int media_parse(libvlc_media_t *media, bool b_async, libvlc_media_parse_flag_t parse_flag) { bool needed; vlc_mutex_lock(&media->parsed_lock); needed = !media->has_asked_preparse; media->has_asked_preparse = true; if (needed) media->is_parsed = false; vlc_mutex_unlock(&media->parsed_lock); if (needed) { libvlc_int_t *libvlc = media->p_libvlc_instance->p_libvlc_int; input_item_t *item = media->p_input_item; input_item_meta_request_option_t art_scope = META_REQUEST_OPTION_NONE; input_item_meta_request_option_t parse_scope = META_REQUEST_OPTION_SCOPE_LOCAL; int ret; if (parse_flag & libvlc_media_fetch_local) art_scope |= META_REQUEST_OPTION_SCOPE_LOCAL; if (parse_flag & libvlc_media_fetch_network) art_scope |= META_REQUEST_OPTION_SCOPE_NETWORK; if (art_scope != META_REQUEST_OPTION_NONE) { ret = libvlc_ArtRequest(libvlc, item, art_scope); if (ret != VLC_SUCCESS) return ret; } if (parse_flag & libvlc_media_parse_network) parse_scope |= META_REQUEST_OPTION_SCOPE_NETWORK; if (parse_flag & libvlc_media_do_interact) parse_scope |= META_REQUEST_OPTION_DO_INTERACT; ret = libvlc_MetaRequest(libvlc, item, parse_scope); if (ret != VLC_SUCCESS) return ret; } else return VLC_EGENERIC; if (!b_async) { vlc_mutex_lock(&media->parsed_lock); while (!media->is_parsed) vlc_cond_wait(&media->parsed_cond, &media->parsed_lock); vlc_mutex_unlock(&media->parsed_lock); } return VLC_SUCCESS; }
void vlc_rwlock_wrlock (vlc_rwlock_t *lock) { vlc_mutex_lock (&lock->mutex); if (unlikely(lock->writers == ULONG_MAX)) abort (); lock->writers++; /* Wait until nobody owns the lock in either way. */ while ((lock->readers > 0) || (lock->writer != 0)) vlc_cond_wait (&lock->wait, &lock->mutex); lock->writers--; assert (lock->writer == 0); lock->writer = _gettid (); vlc_mutex_unlock (&lock->mutex); }
/***************************************************************************** * Close: close the audio device *****************************************************************************/ static void Close ( vlc_object_t *p_this ) { audio_output_t *p_aout = (audio_output_t *)p_this; aout_sys_t *p_sys = p_aout->sys; msg_Dbg( p_aout, "closing portaudio"); #ifdef PORTAUDIO_IS_SERIOUSLY_BROKEN /* Signal end of stream */ vlc_mutex_lock( &pa_thread->lock_signal ); pa_thread->b_signal = true; vlc_cond_signal( &pa_thread->signal ); vlc_mutex_unlock( &pa_thread->lock_signal ); /* Wait until thread is ready */ vlc_mutex_lock( &pa_thread->lock_wait ); while( !pa_thread->b_wait ) vlc_cond_wait( &pa_thread->wait, &pa_thread->lock_wait ); vlc_mutex_unlock( &pa_thread->lock_wait ); pa_thread->b_wait = false; #else int i_err = Pa_StopStream( p_sys->p_stream ); if( i_err != paNoError ) { msg_Err( p_aout, "Pa_StopStream: %d (%s)", i_err, Pa_GetErrorText( i_err ) ); } i_err = Pa_CloseStream( p_sys->p_stream ); if( i_err != paNoError ) { msg_Err( p_aout, "Pa_CloseStream: %d (%s)", i_err, Pa_GetErrorText( i_err ) ); } i_err = Pa_Terminate(); if( i_err != paNoError ) { msg_Err( p_aout, "Pa_Terminate: %d (%s)", i_err, Pa_GetErrorText( i_err ) ); } #endif msg_Dbg( p_aout, "portaudio closed"); aout_PacketDestroy( p_aout ); free( p_sys ); }
static void* EncoderThread( vlc_object_t* p_this ) { sout_stream_sys_t *p_sys = (sout_stream_sys_t*)p_this; sout_stream_id_t *id = p_sys->id_video; picture_t *p_pic; int canc = vlc_savecancel (); while( vlc_object_alive (p_sys) && !p_sys->b_error ) { block_t *p_block; vlc_mutex_lock( &p_sys->lock_out ); while( p_sys->i_last_pic == p_sys->i_first_pic ) { vlc_cond_wait( &p_sys->cond, &p_sys->lock_out ); if( !vlc_object_alive (p_sys) || p_sys->b_error ) break; } if( !vlc_object_alive (p_sys) || p_sys->b_error ) { vlc_mutex_unlock( &p_sys->lock_out ); break; } p_pic = p_sys->pp_pics[p_sys->i_first_pic++]; p_sys->i_first_pic %= PICTURE_RING_SIZE; vlc_mutex_unlock( &p_sys->lock_out ); video_timer_start( id->p_encoder ); p_block = id->p_encoder->pf_encode_video( id->p_encoder, p_pic ); video_timer_stop( id->p_encoder ); vlc_mutex_lock( &p_sys->lock_out ); block_ChainAppend( &p_sys->p_buffers, p_block ); vlc_mutex_unlock( &p_sys->lock_out ); picture_Release( p_pic ); } while( p_sys->i_last_pic != p_sys->i_first_pic ) { p_pic = p_sys->pp_pics[p_sys->i_first_pic++]; p_sys->i_first_pic %= PICTURE_RING_SIZE; picture_Release( p_pic ); } block_ChainRelease( p_sys->p_buffers ); vlc_restorecancel (canc); return NULL; }
void vlc_rwlock_rdlock (vlc_rwlock_t *lock) { vlc_mutex_lock (&lock->mutex); /* Recursive read-locking is allowed. We only need to ensure that there is * no active writer. */ while (lock->writer != 0) { assert (lock->readers == 0); vlc_cond_wait (&lock->wait, &lock->mutex); } if (unlikely(lock->readers == ULONG_MAX)) abort (); lock->readers++; vlc_mutex_unlock (&lock->mutex); }
/**************************************************************************** * HttpCallback: Return the index.html file ****************************************************************************/ static int HttpCallback( httpd_file_sys_t *p_args, httpd_file_t *p_file, uint8_t *_psz_request, uint8_t **_pp_data, int *pi_data ) { VLC_UNUSED(p_file); access_sys_t *p_sys = p_args->p_access->p_sys; char *psz_request = (char *)_psz_request; char **pp_data = (char **)_pp_data; vlc_mutex_lock( &p_sys->httpd_mutex ); p_sys->i_httpd_timeout = mdate() + INT64_C(3000000); /* 3 s */ p_sys->psz_request = psz_request; p_sys->b_request_frontend_info = true; if ( p_sys->p_cam != NULL ) { p_sys->b_request_mmi_info = true; } else { p_sys->psz_mmi_info = strdup( "No available CAM interface\n" ); } do { vlc_cond_wait( &p_sys->httpd_cond, &p_sys->httpd_mutex ); } while ( p_sys->b_request_frontend_info || p_sys->b_request_mmi_info ); p_sys->i_httpd_timeout = 0; vlc_mutex_unlock( &p_sys->httpd_mutex ); *pi_data = strlen( psz_constant_header ) + strlen( p_sys->psz_mmi_info ) + strlen( psz_constant_middle ) + strlen( p_sys->psz_frontend_info ) + strlen( psz_constant_footer ) + 1; *pp_data = malloc( *pi_data ); sprintf( *pp_data, "%s%s%s%s%s", psz_constant_header, p_sys->psz_mmi_info, psz_constant_middle, p_sys->psz_frontend_info, psz_constant_footer ); free( p_sys->psz_frontend_info ); free( p_sys->psz_mmi_info ); return VLC_SUCCESS; }
VLC_NORETURN static void *vlc_timer_thread (void *data) { struct vlc_timer *timer = data; vlc_mutex_lock (&timer->lock); mutex_cleanup_push (&timer->lock); for (;;) { while (timer->value == 0) vlc_cond_wait (&timer->reschedule, &timer->lock); if (vlc_cond_timedwait (&timer->reschedule, &timer->lock, timer->value) == 0) continue; if (timer->interval == 0) timer->value = 0; /* disarm */ vlc_mutex_unlock (&timer->lock); int canc = vlc_savecancel (); timer->func (timer->data); vlc_restorecancel (canc); mtime_t now = mdate (); unsigned misses; vlc_mutex_lock (&timer->lock); if (timer->interval == 0) continue; misses = (now - timer->value) / timer->interval; timer->value += timer->interval; /* Try to compensate for one miss (mwait() will return immediately) * but no more. Otherwise, we might busy loop, after extended periods * without scheduling (suspend, SIGSTOP, RT preemption, ...). */ if (misses > 1) { misses--; timer->value += misses * timer->interval; atomic_fetch_add_explicit (&timer->overruns, misses, memory_order_relaxed); } } vlc_cleanup_pop (); vlc_assert_unreachable (); }
/***************************************************************************** * Run: main thread *****************************************************************************/ static void *Run( void *data ) { services_discovery_t *p_sd = data; services_discovery_sys_t *p_sys = p_sd->p_sys; vlc_mutex_lock( &p_sys->lock ); mutex_cleanup_push( &p_sys->lock ); for( ;; ) { while( !p_sys->b_update ) vlc_cond_wait( &p_sys->wait, &p_sys->lock ); int canc = vlc_savecancel (); msg_Dbg( p_sd, "Update required" ); if( p_sys->update_type == UPDATE_URLS ) { char* psz_urls = var_GetNonEmptyString( p_sd, "podcast-urls" ); ParseUrls( p_sd, psz_urls ); free( psz_urls ); } else if( p_sys->update_type == UPDATE_REQUEST ) { ParseRequest( p_sd ); } p_sys->b_update = false; for( int i = 0; i < p_sd->p_sys->i_input; i++ ) { input_thread_t *p_input = p_sd->p_sys->pp_input[i]; if( p_input->b_eof || p_input->b_error ) { input_Stop( p_input, false ); vlc_thread_join( p_input ); vlc_object_release( p_input ); p_sd->p_sys->pp_input[i] = NULL; REMOVE_ELEM( p_sys->pp_input, p_sys->i_input, i ); i--; } } vlc_restorecancel (canc); } vlc_cleanup_pop(); assert(0); /* dead code */ }