Ejemplo n.º 1
0
bool CSocket::Send( const char* pszData, long nLen )
{
	bool bResult = false;

	do
	{
		bool bLoopError = false;
		int nSendLen = 0, nRes = 0, nNetLen = htonl( nLen );

		m_nBytesWritten = 0;

		if( !nLen ) LOG_ERROR_BREAK( "Send data is empty" );
		if( !pszData ) LOG_ERROR_BREAK( "pszData is NULL" );

		m_tvTimeOut.tv_sec  = (long)m_nRwTimeOut;
		m_tvTimeOut.tv_usec = 0;

		FD_ZERO( &m_fdWriteSockets );
		FD_SET( m_sockMain, &m_fdWriteSockets );
		if( SOCKET_ERROR == (nRes = select(int(m_sockMain)+1, 0, &m_fdWriteSockets, 0, &m_tvTimeOut)) ) {
			LOG_ERROR3_BREAK( szErrorFailedWithCodeFmt, "select", WSAGetLastError() );
		}

		if( !nRes ) LOG_ERROR_BREAK( szSocketNotReady );
		if( !FD_ISSET(m_sockMain, &m_fdWriteSockets) ) LOG_ERROR_BREAK( "Timeout elapsed" );

		if( m_bUseHeaderLength )
		{	
			nSendLen = send( m_sockMain, (char*)&nNetLen, sizeof(nNetLen), 0 );
			if( SOCKET_ERROR == nSendLen || !nSendLen ) {
				LOG_ERROR3_BREAK( szErrorFailedWithCodeFmt, "send", WSAGetLastError() );
			}
		}

		while( nLen > 0 )
		{
			nSendLen = send( m_sockMain, pszData, nLen, 0 );
			if( SOCKET_ERROR == nSendLen || !nSendLen ) {
				LOG_ERROR3( szErrorFailedWithCodeFmt, "send", WSAGetLastError() );
				bLoopError = true;
				break;
			}
			nLen -= nSendLen;
			pszData += nSendLen;
			m_nBytesWritten += nSendLen;
		}

		if( bLoopError ) break;
		bResult = true;
	}
	while( false );

	return bResult;
}
Ejemplo n.º 2
0
bool CSocket::Shutdown( int nHow /* = SD_BOTH */ )
{
	bool bResult = true;
	if( shutdown(m_sockMain, nHow) ) {
		LOG_ERROR3( szErrorFailedWithCodeFmt, "shutdown", WSAGetLastError() );
		bResult = false;
	}

	m_bConnected = false;
	return bResult;
}
Ejemplo n.º 3
0
int dtd_SetPixelRepetitionInput(dtd_t *dtd, u16 value)
{
	LOG_TRACE();

	switch (dtd->mCode)
	{
	case (u8)-1:
	case 10:
	case 11:
	case 12:
	case 13:
	case 25:
	case 26:
	case 27:
	case 28:
		if (value < 10)
		{
			dtd->mPixelRepetitionInput = value;
			return TRUE;
		}
		break;
	case 14:
	case 15:
	case 29:
	case 30:
		if (value < 2)
		{
			dtd->mPixelRepetitionInput = value;
			return TRUE;
		}
		break;
	case 35:
	case 36:
	case 37:
	case 38:
		if (value < 2 || value == 3)
		{
			dtd->mPixelRepetitionInput = value;
			return TRUE;
		}
		break;
	default:
		if (value == dtd->mPixelRepetitionInput)
		{
			return TRUE;
		}
		break;
	}
	error_Set(ERR_PIXEL_REPETITION_FOR_VIDEO_MODE);
	LOG_ERROR3("Invalid pixel repetition input for video mode", value, dtd->mCode);
	return FALSE;
}
Ejemplo n.º 4
0
void thread_mutex_unlock_c(mutex_t *mutex, int line, char *file)
{
#ifdef DEBUG_MUTEXES
    thread_type *th = thread_self();

    if (!th) {
        LOG_ERROR3("No record for %u in unlock [%s:%d]", thread_self(), file, line);
    }

    LOG_DEBUG5("Unlocking %p (%s) on line %d in file %s by thread %d", mutex, mutex->name, line, file, th ? th->thread_id : -1);

    mutex->line = line;

# ifdef CHECK_MUTEXES
    if (th) {
        int locks = 0;
        avl_node *node;
        mutex_t *tmutex;

        _mutex_lock(&_mutextree_mutex);

        while (node) {
            tmutex = (mutex_t *)node->key;

            if (tmutex->mutex_id == mutex->mutex_id) {
                if (tmutex->thread_id != th->thread_id) {
                    LOG_ERROR7("ILLEGAL UNLOCK (%d != %d) on mutex [%s] in file %s line %d by thread %d [%s]", tmutex->thread_id, th->thread_id,
                         mutex->name ? mutex->name : "undefined", file, line, th->thread_id, th->name);
                    _mutex_unlock(&_mutextree_mutex);
                    return;
                }
            } else if (tmutex->thread_id == th->thread_id) {
                locks++;
            }

            node = avl_get_next (node);
        }

        if ((locks > 0) && (_multi_mutex.thread_id != th->thread_id)) {
            /* Don't have double mutex, has more than this mutex left */

            LOG_WARN("(%d != %d) Thread %d [%s] tries to unlock a mutex [%s] in file %s line %d, without owning double mutex!",
                 _multi_mutex.thread_id, th->thread_id, th->thread_id, th->name, mutex->name ? mutex->name : "undefined", file, line);
        }

        _mutex_unlock(&_mutextree_mutex);
    }
# endif  /* CHECK_MUTEXES */

    _mutex_unlock(mutex);

    _mutex_lock(&_mutextree_mutex);

    LOG_DEBUG2("Unlocked %p by thread %d", mutex, th ? th->thread_id : -1);
    mutex->line = -1;
    if (mutex->thread_id == th->thread_id) {
        mutex->thread_id = MUTEX_STATE_NOTLOCKED;
    }

    _mutex_unlock(&_mutextree_mutex);
#else
    _mutex_unlock(mutex);
#endif /* DEBUG_MUTEXES */
}
Ejemplo n.º 5
0
/* The main loop for each instance. Gets data passed to it from the stream
 * manager (which gets it from the input module), and streams it to the
 * specified server
 */
void *ices_instance_stream(void *arg)
{
	int ret, shouterr;
	ref_buffer *buffer;
	char *connip;
	stream_description *sdsc = arg;
	instance_t *stream = sdsc->stream;
	input_module_t *inmod = sdsc->input;
	int reencoding = (inmod->type == ICES_INPUT_VORBIS) && stream->encode;
	int encoding = (inmod->type == ICES_INPUT_PCM) && stream->encode;
    char *stream_name = NULL, *stream_genre = NULL, *stream_description = NULL;
    char *user = NULL;
	
	vorbis_comment_init(&sdsc->vc);

	sdsc->shout = shout_new();

	/* we only support the ice protocol and vorbis streams currently */
	shout_set_format(sdsc->shout, SHOUT_FORMAT_VORBIS);
	//shout_set_protocol(sdsc->shout, SHOUT_PROTOCOL_ICE);
	shout_set_protocol(sdsc->shout, SHOUT_PROTOCOL_HTTP);

    signal(SIGPIPE, signal_hup_handler);

	connip = malloc(16);
	if(!resolver_getip(stream->hostname, connip, 16))
	{
		LOG_ERROR1("Could not resolve hostname \"%s\"", stream->hostname);
		free(connip);
		stream->died = 1;
		return NULL;
	}

	if (!(shout_set_host(sdsc->shout, connip)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}

	shout_set_port(sdsc->shout, stream->port);
	if (!(shout_set_password(sdsc->shout, stream->password)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}
    if (stream->user)
        user = stream->user;
    else
        user = "******";

    if(shout_set_user(sdsc->shout, user) != SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
    }

	if (!(shout_set_agent(sdsc->shout, VERSIONSTRING)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}

	if (!(shout_set_mount(sdsc->shout, stream->mount)) == SHOUTERR_SUCCESS) {
		LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
		free(connip);
		stream->died = 1;
		return NULL;
	}

	/* set the metadata for the stream */
    if(stream->stream_name)
        stream_name = stream->stream_name;
    else if (ices_config->stream_name)
        stream_name = ices_config->stream_name;

    if(stream->stream_description)
        stream_description = stream->stream_description;
    else if (ices_config->stream_description)
        stream_description = ices_config->stream_description;

    if(stream->stream_genre)
        stream_genre = stream->stream_genre;
    else if (ices_config->stream_genre)
        stream_genre = ices_config->stream_genre;

    if(stream_name)
		if (!(shout_set_name(sdsc->shout, stream_name)) == SHOUTERR_SUCCESS) {
			LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
			free(connip);
			stream->died = 1;
			return NULL;
		}
	if (stream_genre)
		if (!(shout_set_genre(sdsc->shout, stream_genre)) == SHOUTERR_SUCCESS) {
			LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
			free(connip);
			stream->died = 1;
			return NULL;
		}
	if (stream_description)
		if (!(shout_set_description(sdsc->shout, stream_description)) == SHOUTERR_SUCCESS) {
			LOG_ERROR1("libshout error: %s\n", shout_get_error(sdsc->shout));
			free(connip);
			stream->died = 1;
			return NULL;
		}

    if(stream->downmix && encoding && stream->channels == 1) {
        stream->channels = 1;
        sdsc->downmix = downmix_initialise();
    }

    if(stream->resampleinrate && stream->resampleoutrate && encoding) {
        stream->samplerate = stream->resampleoutrate;
        sdsc->resamp = resample_initialise(stream->channels, 
                stream->resampleinrate, stream->resampleoutrate);
    }

	if(encoding)
	{
		if(inmod->metadata_update)
			inmod->metadata_update(inmod->internal, &sdsc->vc);
		sdsc->enc = encode_initialise(stream->channels, stream->samplerate,
				stream->managed, stream->min_br, stream->nom_br, stream->max_br,
                stream->quality, stream->serial++, &sdsc->vc);
        if(!sdsc->enc) {
            LOG_ERROR0("Failed to configure encoder");
		    stream->died = 1;
            return NULL; /* FIXME: probably leaking some memory here */
        }
	}
	else if(reencoding)
		sdsc->reenc = reencode_init(stream);

    if(stream->savefilename != NULL) 
    {
        stream->savefile = fopen(stream->savefilename, "wb");
        if(!stream->savefile)
            LOG_ERROR2("Failed to open stream save file %s: %s", 
                    stream->savefilename, strerror(errno));
        else
            LOG_INFO1("Saving stream to file %s", stream->savefilename);
    }

	if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS)
	{
		LOG_INFO3("Connected to server: %s:%d%s", 
				shout_get_host(sdsc->shout), shout_get_port(sdsc->shout), shout_get_mount(sdsc->shout));

		while(1)
		{
			if(stream->buffer_failures > MAX_ERRORS)
			{
				LOG_WARN0("Too many errors, shutting down");
				break;
			}

			buffer = stream_wait_for_data(stream);

			/* buffer being NULL means that either a fatal error occured,
			 * or we've been told to shut down
			 */
			if(!buffer)
				break;

			/* If data is NULL or length is 0, we should just skip this one.
			 * Probably, we've been signalled to shut down, and that'll be
			 * caught next iteration. Add to the error count just in case,
			 * so that we eventually break out anyway 
			 */
			if(!buffer->buf || !buffer->len)
			{
				LOG_WARN0("Bad buffer dequeued!");
				stream->buffer_failures++;
				continue; 
			}

            if(stream->wait_for_critical)
            {
                LOG_INFO0("Trying restart on new substream");
                stream->wait_for_critical = 0;
            }

            ret = process_and_send_buffer(sdsc, buffer);

            /* No data produced, do nothing */
            if(ret == -1)
                ;
            /* Fatal error */
            else if(ret == -2)
            {
                LOG_ERROR0("Serious error, waiting to restart on "
                           "next substream. Stream temporarily suspended.");
                /* Set to wait until a critical buffer comes through (start of
                 * a new substream, typically), and flush existing queue.
                 */
                thread_mutex_lock(&ices_config->flush_lock);
                stream->wait_for_critical = 1;
                input_flush_queue(stream->queue, 0);
                thread_mutex_unlock(&ices_config->flush_lock);
            }
            /* Non-fatal shout error */
            else if(ret == 0)
			{
				LOG_ERROR2("Send error: %s (%s)", 
                        shout_get_error(sdsc->shout), strerror(errno));
				if(shout_get_errno(sdsc->shout) == SHOUTERR_SOCKET)
				{
					int i=0;

					/* While we're trying to reconnect, don't receive data
					 * to this instance, or we'll overflow once reconnect
					 * succeeds
					 */
					thread_mutex_lock(&ices_config->flush_lock);
					stream->skip = 1;

					/* Also, flush the current queue */
					input_flush_queue(stream->queue, 1);
					thread_mutex_unlock(&ices_config->flush_lock);
					
					while((i < stream->reconnect_attempts ||
							stream->reconnect_attempts==-1) && 
                            !ices_config->shutdown)
					{
						i++;
						LOG_WARN0("Trying reconnect after server socket error");
						shout_close(sdsc->shout);
						if((shouterr = shout_open(sdsc->shout)) == SHOUTERR_SUCCESS)
						{
							LOG_INFO3("Connected to server: %s:%d%s", 
                                    shout_get_host(sdsc->shout), shout_get_port(sdsc->shout), 
                                    shout_get_mount(sdsc->shout));
                            /* This stream can't restart until the next
                             * logical stream comes along, since the
                             * server won't have any cached headers for
                             * this source/connection. So, don't continue
                             * yet.
                             */
                            thread_mutex_lock(&ices_config->flush_lock);
                            stream->wait_for_critical = 1;
                            input_flush_queue(stream->queue, 0);
                            thread_mutex_unlock(&ices_config->flush_lock);
							break;
						}
						else
						{
							LOG_ERROR3("Failed to reconnect to %s:%d (%s)",
								shout_get_host(sdsc->shout),shout_get_port(sdsc->shout),
								shout_get_error(sdsc->shout));
							if(i==stream->reconnect_attempts)
							{
								LOG_ERROR0("Reconnect failed too many times, "
										  "giving up.");
                                /* We want to die now */
								stream->buffer_failures = MAX_ERRORS+1; 
							}
							else /* Don't try again too soon */
								sleep(stream->reconnect_delay); 
						}
					}
					stream->skip = 0;
				}
				stream->buffer_failures++;
			}
			stream_release_buffer(buffer);
		}
	}
	else
	{
		LOG_ERROR3("Failed initial connect to %s:%d (%s)", 
				shout_get_host(sdsc->shout),shout_get_port(sdsc->shout), shout_get_error(sdsc->shout));
	}
	
	shout_close(sdsc->shout);

    if(stream->savefile != NULL) 
        fclose(stream->savefile);

    shout_free(sdsc->shout);
	encode_clear(sdsc->enc);
	reencode_clear(sdsc->reenc);
    downmix_clear(sdsc->downmix);
    resample_clear(sdsc->resamp);
	vorbis_comment_clear(&sdsc->vc);

	stream->died = 1;
	return NULL;
}