static void* Raw1394EventThread( void *obj ) { event_thread_t *p_ev = (event_thread_t *)obj; access_t *p_access = (access_t *) p_ev->p_access; access_sys_t *p_sys = (access_sys_t *) p_access->p_sys; int result = 0; int canc = vlc_savecancel(); AVCPlay( p_access, p_sys->i_node ); vlc_cleanup_push( Raw1394EventThreadCleanup, p_ev ); vlc_restorecancel( canc ); for( ;; ) { while( ( result = poll( &p_sys->raw1394_poll, 1, -1 ) ) < 0 ) { if( errno != EINTR ) msg_Err( p_access, "poll error: %s", vlc_strerror_c(errno) ); } if( result > 0 && ( ( p_sys->raw1394_poll.revents & POLLIN ) || ( p_sys->raw1394_poll.revents & POLLPRI ) ) ) { canc = vlc_savecancel(); result = raw1394_loop_iterate( p_sys->p_raw1394 ); vlc_restorecancel( canc ); } } vlc_cleanup_pop(); vlc_assert_unreachable(); }
/***************************************************************************** * Run: *****************************************************************************/ static void *Run( void *data ) { services_discovery_t *p_sd = data; services_discovery_sys_t *p_sys = p_sd->p_sys; enum type_e i_type = p_sys->i_type; int i, j; int canc = vlc_savecancel(); if( !p_items[i_type].p_children ) { AddSubitemsOfShoutItemURL( p_sd, &p_items[i_type], NULL ); vlc_restorecancel(canc); return NULL; } for( i = 0; p_items[i_type].p_children[i].psz_name; i++ ) { const struct shout_item_t * p_subitem = &p_items[i_type].p_children[i]; if( !p_subitem->p_children ) { AddSubitemsOfShoutItemURL( p_sd, p_subitem, p_subitem->psz_name ); continue; } for( j = 0; p_subitem->p_children[j].psz_name; j++ ) { input_item_t *p_input = CreateInputItemFromShoutItem( p_sd, &p_subitem->p_children[j] ); services_discovery_AddItem( p_sd, p_input, p_subitem->psz_name ); vlc_gc_decref( p_input ); } } vlc_restorecancel(canc); return NULL; }
/***************************************************************************** * 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; }
vlc_tls_t *vlc_tls_ClientSessionCreate (vlc_tls_creds_t *crd, int fd, const char *host, const char *service, const char *const *alpn, char **alp) { vlc_tls_t *session; int canc, val; canc = vlc_savecancel(); session = vlc_tls_SessionCreate (crd, fd, host, alpn); if (session == NULL) { vlc_restorecancel(canc); return NULL; } mtime_t deadline = mdate (); deadline += var_InheritInteger (crd, "ipv4-timeout") * 1000; struct pollfd ufd[1]; ufd[0].fd = fd; vlc_cleanup_push (cleanup_tls, session); while ((val = crd->handshake(crd, session, host, service, alp)) != 0) { if (val < 0) { msg_Err(crd, "TLS session handshake error"); error: vlc_tls_SessionDelete (session); session = NULL; break; } mtime_t now = mdate (); if (now > deadline) now = deadline; assert (val <= 2); ufd[0] .events = (val == 1) ? POLLIN : POLLOUT; vlc_restorecancel(canc); val = poll (ufd, 1, (deadline - now) / 1000); canc = vlc_savecancel(); if (val == 0) { msg_Err(crd, "TLS session handshake timeout"); goto error; } } vlc_cleanup_pop(); vlc_restorecancel(canc); return session; }
/***************************************************************************** * Chromecast thread *****************************************************************************/ static void* chromecastThread(void* p_data) { int canc = vlc_savecancel(); // Not cancellation-safe part. sout_stream_t *p_stream = reinterpret_cast<sout_stream_t*>(p_data); sout_stream_sys_t* p_sys = p_stream->p_sys; p_sys->p_intf->msgAuth(); p_sys->p_intf->sendMessages(); vlc_restorecancel(canc); while (1) { p_sys->p_intf->handleMessages(); vlc_mutex_lock(&p_sys->p_intf->lock); if ( p_sys->p_intf->getConnectionStatus() == CHROMECAST_CONNECTION_DEAD ) { vlc_mutex_unlock(&p_sys->p_intf->lock); break; } vlc_mutex_unlock(&p_sys->p_intf->lock); } return NULL; }
/** * Log a message */ static void Overflow (msg_cb_data_t *p_sys, msg_item_t *p_item, unsigned overruns) { VLC_UNUSED(overruns); int verbosity = var_CreateGetInteger( p_sys->p_intf, "verbose" ); int priority = 0; switch( p_item->i_type ) { case VLC_MSG_WARN: priority = 1; break; case VLC_MSG_DBG: priority = 2; break; } if (verbosity < priority) return; int canc = vlc_savecancel(); switch( p_sys->i_mode ) { case MODE_HTML: HtmlPrint( p_item, p_sys->p_file ); break; #ifdef HAVE_SYSLOG_H case MODE_SYSLOG: SyslogPrint( p_item ); break; #endif case MODE_TEXT: default: TextPrint( p_item, p_sys->p_file ); break; } vlc_restorecancel( canc ); }
/***************************************************************************** * 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; }
static void *Run (void *data) { services_discovery_t *sd = data; services_discovery_sys_t *p_sys = sd->p_sys; xcb_connection_t *conn = p_sys->conn; int fd = xcb_get_file_descriptor (conn); if (fd == -1) return NULL; while (!xcb_connection_has_error (conn)) { xcb_generic_event_t *ev; struct pollfd ufd = { .fd = fd, .events = POLLIN, }; poll (&ufd, 1, -1); int canc = vlc_savecancel (); while ((ev = xcb_poll_for_event (conn)) != NULL) { if ((ev->response_type & 0x7F) == XCB_PROPERTY_NOTIFY) { const xcb_property_notify_event_t *pn = (xcb_property_notify_event_t *)ev; if (pn->atom == p_sys->net_client_list) UpdateApps (sd); } free (ev); } vlc_restorecancel (canc); } return NULL; }
int vlc_poll (struct pollfd *fds, unsigned nfds, int timeout) { struct timespec tsbuf, *ts; sigset_t set; int canc, ret; if (timeout != -1) { div_t d = div (timeout, 1000); tsbuf.tv_sec = d.quot; tsbuf.tv_nsec = d.rem * 1000000; ts = &tsbuf; } else ts = NULL; pthread_sigmask (SIG_BLOCK, NULL, &set); sigdelset (&set, SIGRTMIN); canc = vlc_savecancel (); ret = ppoll (fds, nfds, ts, &set); vlc_restorecancel (canc); vlc_testcancel (); return ret; }
/** Background thread for X11 events handling */ static void *Thread (void *data) { vout_window_t *wnd = data; vout_window_sys_t *p_sys = wnd->sys; xcb_connection_t *conn = p_sys->conn; int fd = xcb_get_file_descriptor (conn); if (fd == -1) return NULL; for (;;) { xcb_generic_event_t *ev; struct pollfd ufd = { .fd = fd, .events = POLLIN, }; poll (&ufd, 1, -1); int canc = vlc_savecancel (); while ((ev = xcb_poll_for_event (conn)) != NULL) { if (ProcessKeyEvent (p_sys->keys, ev) == 0) continue; msg_Dbg (wnd, "unhandled event: %"PRIu8, ev->response_type); free (ev); } vlc_restorecancel (canc); if (xcb_connection_has_error (conn)) { msg_Err (wnd, "X server failure"); break; } } return NULL; }
/** * Requests termination of an object, cancels the object thread, and make the * object wait pipe (if it exists) readable. Not a cancellation point. */ void vlc_object_kill( vlc_object_t *p_this ) { vlc_object_internals_t *priv = vlc_internals( p_this ); int fd = -1; vlc_thread_cancel( p_this ); vlc_mutex_lock( &pipe_lock ); if( !p_this->b_die ) { fd = priv->pipes[1]; p_this->b_die = true; } /* This also serves as a memory barrier toward vlc_object_alive(): */ vlc_mutex_unlock( &pipe_lock ); if (fd != -1) { int canc = vlc_savecancel (); /* write _after_ setting b_die, so vlc_object_alive() returns false */ write (fd, &(uint64_t){ 1 }, sizeof (uint64_t)); msg_Dbg (p_this, "waitpipe: object killed"); vlc_restorecancel (canc); } }
/** Background thread for Wayland shell events handling */ static void *Thread(void *data) { vout_window_t *wnd = data; struct wl_display *display = wnd->display.wl; struct pollfd ufd[1]; int canc = vlc_savecancel(); vlc_cleanup_push(cleanup_wl_display_read, display); ufd[0].fd = wl_display_get_fd(display); ufd[0].events = POLLIN; for (;;) { while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); wl_display_flush(display); vlc_restorecancel(canc); while (poll(ufd, 1, -1) < 0); canc = vlc_savecancel(); wl_display_read_events(display); wl_display_dispatch_pending(display); } vlc_assert_unreachable(); vlc_cleanup_pop(); //vlc_restorecancel(canc); //return NULL; }
static void PrintColorMsg (void *d, int type, const msg_item_t *p_item, const char *format, va_list ap) { const int *pverbose = d; FILE *stream = stderr; if (*pverbose < 0 || *pverbose < (type - VLC_MSG_ERR)) return; int canc = vlc_savecancel (); flockfile (stream); fprintf (stream, "["GREEN"%p"GRAY"] ", (void *)p_item->i_object_id); if (p_item->psz_header != NULL) utf8_fprintf (stream, "[%s] ", p_item->psz_header); utf8_fprintf (stream, "%s %s%s: %s", p_item->psz_module, p_item->psz_object_type, msg_type[type], msg_color[type]); utf8_vfprintf (stream, format, ap); fputs (GRAY"\n", stream); #if defined (WIN32) || defined (__OS2__) fflush (stream); #endif funlockfile (stream); vlc_restorecancel (canc); }
/** * Returns the readable end of a pipe that becomes readable once termination * of the object is requested (vlc_object_kill()). * This can be used to wake-up out of a select() or poll() event loop, such * typically when doing network I/O. * * Note that the pipe will remain the same for the lifetime of the object. * DO NOT read the pipe nor close it yourself. Ever. * * @param obj object that would be "killed" * @return a readable pipe descriptor, or -1 on error. */ int vlc_object_waitpipe( vlc_object_t *obj ) { vlc_object_internals_t *internals = vlc_internals( obj ); vlc_mutex_lock (&pipe_lock); if (internals->pipes[0] == -1) { /* This can only ever happen if someone killed us without locking: */ assert (internals->pipes[1] == -1); /* pipe() is not a cancellation point, but write() is and eventfd() is * unspecified (not in POSIX). */ int canc = vlc_savecancel (); #if defined (HAVE_SYS_EVENTFD_H) internals->pipes[0] = internals->pipes[1] = eventfd (0, EFD_CLOEXEC); if (internals->pipes[0] == -1) #endif { if (pipe (internals->pipes)) internals->pipes[0] = internals->pipes[1] = -1; } if (internals->pipes[0] != -1 && obj->b_die) { /* Race condition: vlc_object_kill() already invoked! */ msg_Dbg (obj, "waitpipe: object already dying"); write (internals->pipes[1], &(uint64_t){ 1 }, sizeof (uint64_t)); } vlc_restorecancel (canc); } vlc_mutex_unlock (&pipe_lock); return internals->pipes[0]; }
static void AndroidPrintMsg(void *opaque, int type, const vlc_log_t *p_item, const char *format, va_list ap) { int prio; char *format2; int verbose = (intptr_t)opaque; if (verbose < type) return; int canc = vlc_savecancel(); if (asprintf(&format2, "[%0*"PRIxPTR"] %s %s: %s", ptr_width, p_item->i_object_id, p_item->psz_module, p_item->psz_object_type, format) < 0) return; switch (type) { case VLC_MSG_INFO: prio = ANDROID_LOG_INFO; break; case VLC_MSG_ERR: prio = ANDROID_LOG_ERROR; break; case VLC_MSG_WARN: prio = ANDROID_LOG_WARN; break; default: case VLC_MSG_DBG: prio = ANDROID_LOG_DEBUG; } __android_log_vprint(prio, "VLC", format2, ap); free(format2); vlc_restorecancel(canc); }
static void vlc_vaLogEarly(void *d, int type, const vlc_log_t *item, const char *format, va_list ap) { vlc_logger_early_t *sys = d; vlc_log_early_t *log = malloc(sizeof (*log)); if (unlikely(log == NULL)) return; log->next = NULL; log->type = type; log->meta.i_object_id = item->i_object_id; /* NOTE: Object types MUST be static constant - no need to copy them. */ log->meta.psz_object_type = item->psz_object_type; log->meta.psz_module = item->psz_module; /* Ditto. */ log->meta.psz_header = item->psz_header ? strdup(item->psz_header) : NULL; log->meta.file = item->file; log->meta.line = item->line; log->meta.func = item->func; int canc = vlc_savecancel(); /* XXX: needed for vasprintf() ? */ if (vasprintf(&log->msg, format, ap) == -1) log->msg = NULL; vlc_restorecancel(canc); vlc_mutex_lock(&sys->lock); assert(sys->tailp != NULL); assert(*(sys->tailp) == NULL); *(sys->tailp) = log; sys->tailp = &log->next; vlc_mutex_unlock(&sys->lock); }
/***************************************************************************** * Run: main loop *****************************************************************************/ static void *Run( void *data ) { intf_thread_t *p_intf = data; intf_sys_t *p_sys = p_intf->p_sys; struct pollfd ufd; ufd.fd = p_sys->i_fd; ufd.events = POLLIN; for( ;; ) { /* Wait for data */ if( poll( &ufd, 1, -1 ) == -1 ) { if( errno == EINTR ) continue; break; } /* Process */ int canc = vlc_savecancel(); Process( p_intf ); vlc_restorecancel(canc); } return NULL; }
static void* Raw1394EventThread( vlc_object_t *p_this ) { event_thread_t *p_ev = (event_thread_t *) p_this; access_t *p_access = (access_t *) p_ev->p_access; access_sys_t *p_sys = (access_sys_t *) p_access->p_sys; int result = 0; int canc = vlc_savecancel (); AVCPlay( p_access, p_sys->i_node ); while( vlc_object_alive (p_sys->p_ev) ) { while( ( result = poll( &(p_sys->raw1394_poll), 1, 200 ) ) < 0 ) { if( !( errno == EAGAIN || errno == EINTR ) ) { perror( "error: raw1394 poll" ); msg_Err( p_access, "retrying device raw1394" ); } } if( !vlc_object_alive (p_sys->p_ev) ) break; if( result > 0 && ( ( p_sys->raw1394_poll.revents & POLLIN ) || ( p_sys->raw1394_poll.revents & POLLPRI ) ) ) result = raw1394_loop_iterate( p_sys->p_raw1394 ); } AVCStop( p_access, p_sys->i_node ); vlc_restorecancel (canc); return NULL; }
static void PrintMsg (void *d, int type, const vlc_log_t *p_item, const char *format, va_list ap) { FILE *stream = stderr; int verbose = (intptr_t)d; if (verbose < 0 || verbose < (type - VLC_MSG_ERR)) return; int canc = vlc_savecancel (); flockfile (stream); utf8_fprintf (stream, "[%0*"PRIxPTR"] ", ptr_width, p_item->i_object_id); if (p_item->psz_header != NULL) utf8_fprintf (stream, "[%s] ", p_item->psz_header); utf8_fprintf (stream, "%s %s%s: ", p_item->psz_module, p_item->psz_object_type, msg_type[type]); utf8_vfprintf (stream, format, ap); putc_unlocked ('\n', stream); #if defined (_WIN32) || defined (__OS2__) fflush (stream); #endif funlockfile (stream); vlc_restorecancel (canc); }
static void *Run (void *data) { services_discovery_t *sd = data; services_discovery_sys_t *p_sys = sd->p_sys; struct udev_monitor *mon = p_sys->monitor; int fd = udev_monitor_get_fd (mon); struct pollfd ufd = { .fd = fd, .events = POLLIN, }; for (;;) { while (poll (&ufd, 1, -1) == -1) if (errno != EINTR) break; int canc = vlc_savecancel (); struct udev_device *dev = udev_monitor_receive_device (mon); if (dev == NULL) continue; const char *action = udev_device_get_action (dev); if (!strcmp (action, "add")) AddDevice (sd, dev); else if (!strcmp (action, "remove")) RemoveDevice (sd, dev); else if (!strcmp (action, "change")) { RemoveDevice (sd, dev); AddDevice (sd, dev); } udev_device_unref (dev); vlc_restorecancel (canc); } return NULL; }
/* Reports a fatal error from the threading layer, for debugging purposes. */ static void vlc_thread_fatal (const char *action, int error, const char *function, const char *file, unsigned line) { int canc = vlc_savecancel (); fprintf (stderr, "LibVLC fatal error %s (%d) in thread %lu ", action, error, vlc_threadid ()); vlc_trace (function, file, line); char buf[1000]; const char *msg; switch (strerror_r (error, buf, sizeof (buf))) { case 0: msg = buf; break; case ERANGE: /* should never happen */ msg = "unknown (too big to display)"; break; default: msg = "unknown (invalid error number)"; break; } fprintf (stderr, " Error message: %s\n", msg); fflush (stderr); vlc_restorecancel (canc); abort (); }
/***************************************************************************** * Decrement an object refcount * And destroy the object if its refcount reach zero. *****************************************************************************/ void vlc_object_release( vlc_object_t *p_this ) { vlc_object_internals_t *internals = vlc_internals( p_this ); vlc_object_t *parent = NULL; bool b_should_destroy; vlc_spin_lock( &internals->ref_spin ); assert( internals->i_refcount > 0 ); if( internals->i_refcount > 1 ) { /* Fast path */ /* There are still other references to the object */ internals->i_refcount--; vlc_spin_unlock( &internals->ref_spin ); return; } vlc_spin_unlock( &internals->ref_spin ); /* Slow path */ /* Remember that we cannot hold the spin while waiting on the mutex */ libvlc_lock (p_this->p_libvlc); /* Take the spin again. Note that another thread may have held the * object in the (very short) mean time. */ vlc_spin_lock( &internals->ref_spin ); b_should_destroy = --internals->i_refcount == 0; vlc_spin_unlock( &internals->ref_spin ); if( b_should_destroy ) { /* Detach from parent to protect against FIND_CHILDREN */ parent = p_this->p_parent; if (likely(parent)) { /* Unlink */ if (internals->prev != NULL) internals->prev->next = internals->next; else vlc_internals(parent)->first = internals->next; if (internals->next != NULL) internals->next->prev = internals->prev; } /* We have no children */ assert (internals->first == NULL); } libvlc_unlock (p_this->p_libvlc); if( b_should_destroy ) { int canc; canc = vlc_savecancel (); vlc_object_destroy( p_this ); vlc_restorecancel (canc); if (parent) vlc_object_release (parent); } }
void vlc_tls_SessionDelete (vlc_tls_t *session) { int canc = vlc_savecancel(); session->close(session); vlc_restorecancel(canc); free(session); }
static void *DemuxThread( void *p_data ) { demux_t *p_demux = (demux_t *) p_data; demux_sys_t *p_sys = p_demux->p_sys; vlc_tick_t i_next_frame_date = vlc_tick_now() + p_sys->i_frame_interval; int i_status; for(;;) { p_sys->i_cancel_state = vlc_savecancel(); i_status = WaitForMessage( p_sys->p_client, p_sys->i_frame_interval ); vlc_restorecancel( p_sys->i_cancel_state ); /* Ensure we're not building frames too fast */ /* as WaitForMessage takes only a maximum wait */ vlc_tick_wait( i_next_frame_date ); i_next_frame_date += p_sys->i_frame_interval; if ( i_status > 0 ) { p_sys->p_client->frameBuffer = p_sys->p_block->p_buffer; p_sys->i_cancel_state = vlc_savecancel(); i_status = HandleRFBServerMessage( p_sys->p_client ); vlc_restorecancel( p_sys->i_cancel_state ); if ( ! i_status ) { msg_Warn( p_demux, "Cannot get announced data. Server closed ?" ); es_out_Del( p_demux->out, p_sys->es ); p_sys->es = NULL; return NULL; } else { block_t *p_block = block_Duplicate( p_sys->p_block ); if ( p_block ) /* drop frame/content if no next block */ { p_sys->p_block->i_dts = p_sys->p_block->i_pts = vlc_tick_now(); es_out_SetPCR( p_demux->out, p_sys->p_block->i_pts ); es_out_Send( p_demux->out, p_sys->es, p_sys->p_block ); p_sys->p_block = p_block; } } } } return NULL; }
static void *Thread( void *p_data ) { intf_thread_t *p_intf = p_data; intf_sys_t *p_sys = p_intf->p_sys; xcb_connection_t *p_connection = p_sys->p_connection; int canc = vlc_savecancel(); /* */ xcb_flush( p_connection ); /* */ int fd = xcb_get_file_descriptor( p_connection ); for( ;; ) { /* Wait for x11 event */ vlc_restorecancel( canc ); struct pollfd fds = { .fd = fd, .events = POLLIN, }; if( poll( &fds, 1, -1 ) < 0 ) { if( errno != EINTR ) break; canc = vlc_savecancel(); continue; } canc = vlc_savecancel(); xcb_generic_event_t *p_event; while( ( p_event = xcb_poll_for_event( p_connection ) ) ) { if( ( p_event->response_type & 0x7f ) != XCB_KEY_PRESS ) { free( p_event ); continue; } xcb_key_press_event_t *e = (xcb_key_press_event_t *)p_event; for( int i = 0; i < p_sys->i_map; i++ ) { hotkey_mapping_t *p_map = &p_sys->p_map[i]; for( int j = 0; p_map->p_keys[j] != XCB_NO_SYMBOL; j++ ) if( p_map->p_keys[j] == e->detail && p_map->i_modifier == e->state ) { var_SetInteger( p_intf->p_libvlc, "global-key-pressed", p_map->i_vlc ); goto done; } } done: free( p_event ); } } return NULL; }
/***************************************************************************** * 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; }
/***************************************************************************** * RunIntf: main loop *****************************************************************************/ static void RunIntf( intf_thread_t *p_intf ) { int canc = vlc_savecancel( ); /* Main loop */ while( vlc_object_alive( p_intf ) ) { vlc_mutex_lock( &p_intf->p_sys->lock ); /* Notify the interfaces */ if( p_intf->p_sys->b_triggered ) { var_SetBool( p_intf->p_libvlc, "intf-show", true ); p_intf->p_sys->b_triggered = false; } vlc_mutex_unlock( &p_intf->p_sys->lock ); /* Take care of the video output */ if( p_intf->p_sys->p_vout && !vlc_object_alive (p_intf->p_sys->p_vout) ) { var_DelCallback( p_intf->p_sys->p_vout, "mouse-moved", MouseEvent, p_intf ); var_DelCallback( p_intf->p_sys->p_vout, "mouse-button-down", MouseEvent, p_intf ); vlc_object_release( p_intf->p_sys->p_vout ); p_intf->p_sys->p_vout = NULL; } if( p_intf->p_sys->p_vout == NULL ) { p_intf->p_sys->p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_intf->p_sys->p_vout ) { var_AddCallback( p_intf->p_sys->p_vout, "mouse-moved", MouseEvent, p_intf ); var_AddCallback( p_intf->p_sys->p_vout, "mouse-button-down", MouseEvent, p_intf ); } } /* Wait a bit */ msleep( INTF_IDLE_SLEEP ); } if( p_intf->p_sys->p_vout ) { var_DelCallback( p_intf->p_sys->p_vout, "mouse-moved", MouseEvent, p_intf ); var_DelCallback( p_intf->p_sys->p_vout, "mouse-button-down", MouseEvent, p_intf ); vlc_object_release( p_intf->p_sys->p_vout ); } vlc_restorecancel( canc ); }
static void Run ( intf_thread_t *p_intf ) { for( ;; ) { if( dbus_connection_get_dispatch_status(p_intf->p_sys->p_conn) == DBUS_DISPATCH_COMPLETE ) msleep( INTF_IDLE_SLEEP ); int canc = vlc_savecancel(); dbus_connection_read_write_dispatch( p_intf->p_sys->p_conn, 0 ); /* Get the list of events to process * * We can't keep the lock on p_intf->p_sys->p_events, else we risk a * deadlock: * The signal functions could lock mutex X while p_events is locked; * While some other function in vlc (playlist) might lock mutex X * and then set a variable which would call AllCallback(), which itself * needs to lock p_events to add a new event. */ vlc_mutex_lock( &p_intf->p_sys->lock ); int i_events = vlc_array_count( p_intf->p_sys->p_events ); callback_info_t* info[i_events]; for( int i = i_events - 1; i >= 0; i-- ) { info[i] = vlc_array_item_at_index( p_intf->p_sys->p_events, i ); vlc_array_remove( p_intf->p_sys->p_events, i ); } vlc_mutex_unlock( &p_intf->p_sys->lock ); for( int i = 0; i < i_events; i++ ) { switch( info[i]->signal ) { case SIGNAL_ITEM_CURRENT: TrackChange( p_intf ); break; case SIGNAL_INTF_CHANGE: case SIGNAL_PLAYLIST_ITEM_APPEND: case SIGNAL_PLAYLIST_ITEM_DELETED: TrackListChangeEmit( p_intf, info[i]->signal, info[i]->i_node ); break; case SIGNAL_RANDOM: case SIGNAL_REPEAT: case SIGNAL_LOOP: StatusChangeEmit( p_intf ); break; case SIGNAL_STATE: StateChange( p_intf, info[i]->i_input_state ); break; default: assert(0); } free( info[i] ); } vlc_restorecancel( canc ); } }
static void *Thread (void *data) { stream_t *stream = data; stream_sys_t *p_sys = stream->p_sys; #ifdef HAVE_VMSPLICE ssize_t page_mask = sysconf (_SC_PAGE_SIZE) - 1; #endif int fd = p_sys->write_fd; bool error = false; do { ssize_t len; int canc = vlc_savecancel (); #ifdef HAVE_VMSPLICE unsigned char *buf = mmap (NULL, bufsize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); vlc_cleanup_push (cleanup_mmap, buf); #else unsigned char buf[bufsize]; #endif len = stream_Read (stream->p_source, buf, bufsize); vlc_restorecancel (canc); error = len <= 0; for (ssize_t i = 0, j; i < len; i += j) { #ifdef HAVE_VMSPLICE if ((len - i) <= page_mask) /* incomplete last page */ j = write (fd, buf + i, len - i); else { struct iovec iov = { buf + i, (len - i) & ~page_mask, }; j = vmsplice (fd, &iov, 1, SPLICE_F_GIFT); } if (j == -1 && errno == ENOSYS) /* vmsplice() not supported */ #endif j = write (fd, buf + i, len - i); if (j <= 0) { if (j == 0) errno = EPIPE; msg_Err (stream, "cannot write data (%m)"); error = true; break; } } #ifdef HAVE_VMSPLICE vlc_cleanup_run (); /* munmap (buf, bufsize) */ #endif } while (!error); msg_Dbg (stream, "compressed stream at EOF"); return NULL; }
/***************************************************************************** * ThreadControl: manage control messages and pipe media to Read *****************************************************************************/ static void* ThreadControl( void *p_this ) { rtmp_control_thread_t *p_thread = p_this; rtmp_packet_t *rtmp_packet; int canc = vlc_savecancel (); rtmp_init_handler( p_thread->rtmp_handler ); for( ;; ) { vlc_restorecancel( canc ); rtmp_packet = rtmp_read_net_packet( p_thread ); canc = vlc_savecancel( ); if( rtmp_packet != NULL ) { if( rtmp_packet->content_type < 0x01 /* RTMP_CONTENT_TYPE_CHUNK_SIZE */ || rtmp_packet->content_type > 0x14 ) /* RTMP_CONTENT_TYPE_INVOKE */ { free( rtmp_packet->body->body ); free( rtmp_packet->body ); free( rtmp_packet ); msg_Warn( p_thread, "unknown content type received" ); } else p_thread->rtmp_handler[rtmp_packet->content_type]( p_thread, rtmp_packet ); } else { /* Sometimes server close connection too soon */ #warning Locking bug here. if( p_thread->result_connect ) { vlc_mutex_lock( &p_thread->lock ); vlc_cond_signal( &p_thread->wait ); vlc_mutex_unlock( &p_thread->lock ); } break; } } vlc_restorecancel (canc); return NULL; }