static void handler( msg_cb_data_t *d, msg_item_t *p_item, unsigned i_drop ) { if (p_item->i_type > d->verbosity) return; vlc_spin_lock (&d->lock); if (d->count < VLC_MSG_QSIZE) { d->items[d->count++] = p_item; msg_Hold (p_item); } vlc_spin_unlock (&d->lock); (void)i_drop; }
MsgEvent( msg_item_t *msg ) : QEvent( (QEvent::Type)MsgEvent_Type ), msg(msg) { msg_Hold( msg ); }
/** * Add a message to a queue * * This function provides basic functionnalities to other msg_* functions. * It adds a message to a queue (after having printed all stored messages if it * is full). If the message can't be converted to string in memory, it issues * a warning. */ static void QueueMsg( vlc_object_t *p_this, int i_type, const char *psz_module, const char *psz_format, va_list _args ) { assert (p_this); libvlc_priv_t *priv = libvlc_priv (p_this->p_libvlc); int i_header_size; /* Size of the additionnal header */ vlc_object_t *p_obj; char * psz_str = NULL; /* formatted message string */ char * psz_header = NULL; va_list args; if( p_this->i_flags & OBJECT_FLAGS_QUIET || (p_this->i_flags & OBJECT_FLAGS_NODBG && i_type == VLC_MSG_DBG) ) return; #ifndef __GLIBC__ /* Expand %m to strerror(errno) - only once */ char buf[strlen( psz_format ) + 2001], *ptr; strcpy( buf, psz_format ); ptr = (char*)buf; psz_format = (const char*) buf; for( ;; ) { ptr = strchr( ptr, '%' ); if( ptr == NULL ) break; if( ptr[1] == 'm' ) { char errbuf[2001]; size_t errlen; #ifndef WIN32 strerror_r( errno, errbuf, 1001 ); #else int sockerr = WSAGetLastError( ); if( sockerr ) { strncpy( errbuf, net_strerror( sockerr ), 1001 ); WSASetLastError( sockerr ); } if ((sockerr == 0) || (strcmp ("Unknown network stack error", errbuf) == 0)) strncpy( errbuf, strerror( errno ), 1001 ); #endif errbuf[1000] = 0; /* Escape '%' from the error string */ for( char *percent = strchr( errbuf, '%' ); percent != NULL; percent = strchr( percent + 2, '%' ) ) { memmove( percent + 1, percent, strlen( percent ) + 1 ); } errlen = strlen( errbuf ); memmove( ptr + errlen, ptr + 2, strlen( ptr + 2 ) + 1 ); memcpy( ptr, errbuf, errlen ); break; /* Only once, so we don't overflow */ } /* Looks for conversion specifier... */ do ptr++; while( *ptr && ( strchr( "diouxXeEfFgGaAcspn%", *ptr ) == NULL ) ); if( *ptr ) ptr++; /* ...and skip it */ } #endif /* Convert message to string */ vlc_va_copy( args, _args ); if( vasprintf( &psz_str, psz_format, args ) == -1 ) psz_str = NULL; va_end( args ); if( psz_str == NULL ) { int canc = vlc_savecancel (); /* Do not print half of a message... */ #ifdef __GLIBC__ fprintf( stderr, "main warning: can't store message (%m): " ); #else char psz_err[1001]; #ifndef WIN32 /* we're not using GLIBC, so we are sure that the error description * will be stored in the buffer we provide to strerror_r() */ strerror_r( errno, psz_err, 1001 ); #else strncpy( psz_err, strerror( errno ), 1001 ); #endif psz_err[1000] = '\0'; fprintf( stderr, "main warning: can't store message (%s): ", psz_err ); #endif vlc_va_copy( args, _args ); /* We should use utf8_vfprintf - but it calls malloc()... */ vfprintf( stderr, psz_format, args ); va_end( args ); fputs( "\n", stderr ); vlc_restorecancel (canc); return; } msg_item_t * p_item = malloc (sizeof (*p_item)); if (p_item == NULL) return; /* Uho! */ vlc_gc_init (p_item, msg_Free); p_item->psz_module = p_item->psz_msg = p_item->psz_header = NULL; i_header_size = 0; p_obj = p_this; while( p_obj != NULL ) { char *psz_old = NULL; if( p_obj->psz_header ) { i_header_size += strlen( p_obj->psz_header ) + 4; if( psz_header ) { psz_old = strdup( psz_header ); psz_header = (char*)realloc( psz_header, i_header_size ); snprintf( psz_header, i_header_size , "[%s] %s", p_obj->psz_header, psz_old ); } else { psz_header = (char *)malloc( i_header_size ); snprintf( psz_header, i_header_size, "[%s]", p_obj->psz_header ); } } free( psz_old ); p_obj = p_obj->p_parent; } /* Fill message information fields */ p_item->i_type = i_type; p_item->i_object_id = (uintptr_t)p_this; p_item->psz_object_type = p_this->psz_object_type; p_item->psz_module = strdup( psz_module ); p_item->psz_msg = psz_str; p_item->psz_header = psz_header; PrintMsg( p_this, p_item ); msg_bank_t *p_queue = &QUEUE; vlc_mutex_lock( &p_queue->lock ); #define bank p_queue for (int i = 0; i < bank->i_sub; i++) { msg_subscription_t *sub = bank->pp_sub[i]; if ((sub->end + 1 - sub->begin) % VLC_MSG_QSIZE) { sub->items[sub->end++] = msg_Hold (p_item); if (sub->end == VLC_MSG_QSIZE) sub->end = 0; } else sub->overruns++; } vlc_cond_broadcast (&bank->wait); vlc_mutex_unlock (&bank->lock); msg_Release (p_item); }