Beispiel #1
0
static int __uh_raw_send(struct client *cl, const char *buf, int len, int sec,
						 int (*wfn) (struct client *, const char *, int))
{
	ssize_t rv;
	int fd = cl->fd.fd;

	while (true)
	{
		if ((rv = wfn(cl, buf, len)) < 0)
		{
			if (errno == EINTR)
			{
				D("IO: FD(%d) interrupted\n", cl->fd.fd);
				continue;
			}
			else if ((sec > 0) && (errno == EAGAIN || errno == EWOULDBLOCK))
			{
				if (!uh_socket_wait(fd, sec, true))
					return -1;
			}
			else
			{
				D("IO: FD(%d) write error: %s\n", fd, strerror(errno));
				return -1;
			}
		}
		/*
		 * It is not entirely clear whether rv = 0 on nonblocking sockets
		 * is an error. In real world fuzzing tests, not handling it as close
		 * led to tight infinite loops in this send procedure, so treat it as
		 * closed and break out.
		 */
		else if (rv == 0)
		{
			D("IO: FD(%d) appears closed\n", fd);
			return 0;
		}
		else if (rv < len)
		{
			D("IO: FD(%d) short write %d/%d bytes\n", fd, rv, len);
			len -= rv;
			buf += rv;
			continue;
		}
		else
		{
			D("IO: FD(%d) sent %d/%d bytes\n", fd, rv, len);
			return rv;
		}
	}
}
Beispiel #2
0
/*!
 * This function uses the Danielson-Lanczos lemma to compute the Fourier
 * transform of the even and odd sections of the set of items in the list whose
 * index is denoted by s * k + o, where s and o are the given stride and
 * offset, and k is an integer starting from 0.
 *
 * This function is recursive, and assumes that its inputs have already been
 * setup for it in advance. One should call s_naive_fft() first, to ensure that
 * this function is called correctly.
 *
 * \param dft The dft to store the result in.
 * \param dfto The amount to subtract from the offset for the DFT.
 * \param raw The raw data to transform.
 * \param s The stride to iterate over the list with.
 * \param o The offset to iterate over the list with.
 * \param bign the length of the list being iterated over.
 * \param wfn The window function to use, or NULL.
 * \param orgO The offset given to the first call in this recursive chain.
 * \param orgN The N length given to the first call in this recursive chain.
 * \return 0 on success, or an error number otherwise.
 */
int s_fft_r(s_dft_t *dft, size_t dfto, const s_raw_audio_t *raw,
	size_t s, size_t o, size_t bign, double (*wfn)(int32_t, size_t),
	size_t orgO, size_t orgN)
{
	int r;

	double window;

	size_t es;
	size_t eo;
	size_t os;
	size_t oo;

	size_t half;

	size_t idx;

	double bigw;
	s_complex_t bigwl;
	s_complex_t bigwu;

	const s_complex_t *even = NULL;
	const s_complex_t *odd = NULL;

	s_complex_t *dstl = NULL;
	s_complex_t *dstu = NULL;

	/*
	 * Noting that fft(x) = x when x is of length 1, so if we've divided to
	 * the point where we have a list of length 1, just copy the value from
	 * our raw list.
	 */

	if(bign == 1)
	{
		dft->dft[o - dfto].r = (double) s_mono_sample(raw->samples[o]);
		dft->dft[o - dfto].i = 0.0;

		if(wfn != NULL)
		{
			window = wfn(o - orgO, orgN);
			dft->dft[o - dfto].r *= window;
		}

		return 0;
	}

	// Compute the stride and offset for the even and odd elements.

	es = 2 * s;
	eo = o;

	os = 2 * s;
	oo = o + s;

	// Compute the DFT of the even elements.

	r = s_fft_r(dft, dfto, raw, es, eo, bign / 2, wfn, orgO, orgN);

	if(r < 0)
		return r;

	// Compute the DFT of the odd elements.

	r = s_fft_r(dft, dfto, raw, os, oo, bign / 2, wfn, orgO, orgN);

	if(r < 0)
		return r;

	half = bign / 2;

	/*
	 * We need to create a copy of the DFT values as-is, since we need to
	 * use them to combine the even and odd DFT's so that we'll have
	 * computed the correct DFT for this level.
	 */

	s_complex_t *dftprime = malloc(sizeof(s_complex_t) * bign);

	if(dftprime == NULL)
		return -ENOMEM;

	for(idx = 0; idx < bign; ++idx)
		dftprime[idx] = dft->dft[s * idx + o - dfto];

	/*
	 * Per the Danielson-Lanczos lemma, we have that:
	 *
	 *     $F_n = F^e_n + W^n F^o_n$
	 *
	 * Where:
	 *
	 *     $W = e^{-2\pi i/N}$
	 *
	 * Also, because our inputs are real, the DFT is symmetric, so the
	 * result values in the lower and upper halves are based upon the same
	 * values of $F^e_N$ and $F^o_n$. Because of this, we set 2 values per
	 * iteration, using different values of $W$ for each.
	 */

	for(idx = 0; idx < half; ++idx)
	{
		/*
		 * Compute the two $W$ values we'll use, according to the
		 * aforementioned formula.
		 */

		bigw = -2.0 * M_PI / ((double) bign);

		s_cexp(&bigwl, bigw * ((double) idx));
		s_cexp(&bigwu, bigw * ((double) (idx + half)));

		/*
		 * For brevity later on, get pointers to the even and odd
		 * values we will use in our computation.
		 */

		even = &(dftprime[2 * idx]);
		odd = &(dftprime[2 * idx + 1]);

		// Compute the lower-half result value.

		dstl = &(dft->dft[s * idx + o - dfto]);
		s_cmul(dstl, &bigwl, odd);
		s_cadd(dstl, even, dstl);

		// Compute the upper-half result value.

		dstu = &(dft->dft[s * (idx + half) + o - dfto]);
		s_cmul(dstu, &bigwu, odd);
		s_cadd(dstu, even, dstu);

#ifdef SPECTR_DEBUG
		// Make sure we didn't overflow or do anything wrong.

		assert(!isnan(even->r));
		assert(!isinf(even->r));

		assert(!isnan(even->i));
		assert(!isinf(even->i));

		assert(!isnan(odd->r));
		assert(!isinf(odd->r));

		assert(!isnan(odd->i));
		assert(!isinf(odd->i));
#endif
	}

	// Done!

	free(dftprime);

	return 0;
}
/**
   take in a configuration xml document and a system
   context and initialize the transport
*/
int
RpcHttpTransport::init(
    const DOMNode* config,
    RefCountedPtr<SysContext>& ctx,
    iRpcServer* masterServer)
{
    int res = -1;

    ASSERT_D(status() == keRpcNoState);

    REFCOUNTED_CAST(iSysComponent, StdLogger, ctx->getComponent( StdLogger::getRegistryName()), _logger);

    RefCountedPtr<ThdPool> pool;
    REFCOUNTED_CAST(iSysComponent, ThdPool, ctx->getComponent( ThdPool::getRegistryName()), pool);
    ASSERT_D(pool != NULL);

    // inititalize socket environment
    if (( config != NULL ) && ( config->getNodeType() == DOMNode::ELEMENT_NODE ))
    {
        const DOMElement* configElem = (const DOMElement*)config;

        String val;
        Mapping attrs;

        // first configure the server attributes
        DOMNodeList* nodes = DomUtils::getNodeList( configElem, RPC_LISTEN_PORT );
        if ( DomUtils::getNodeValue( (const DOMElement*)nodes->item( 0 ), &val, &attrs ) )
        {
            Mapping::const_iterator it = attrs.find( RPC_BACKLOG_ATTR );
            if( it != attrs.end() )
            {
                _port = StringUtils::toInt( val );
                _backlog = StringUtils::toInt( (*it).second );
            }
            else
            {
                CBLOGERR(_logger,
                         NTEXT("RpcHttpClientTransport::init: can't find attributes to server listener, using defaults"));
            }
        }


        // now configure the client attributes
        attrs.clear();
        nodes = DomUtils::getNodeList( configElem, RPC_PROXY_NAME );
        if ( DomUtils::getNodeValue( (const DOMElement*)nodes->item( 0 ), &val, &attrs ) )
        {
            Mapping::const_iterator it = attrs.find( RPC_PROXY_PORTATTR );
            if( it != attrs.end() )
            {
                _proxy = val;
                _proxyPort = StringUtils::toInt( (*it).second );
            }
            else
            {
                CBLOGERR(_logger,
                         NTEXT("RpcHttpClientTransport::init: can't find attributes to configure Proxy Port"));
            }
        }

        attrs.clear();
        nodes = DomUtils::getNodeList( configElem, RPC_CLIENT_RETRIES );
        if ( DomUtils::getNodeValue( (const DOMElement*)nodes->item( 0 ), &val, &attrs ) )
        {
            Mapping::const_iterator it = attrs.find( RPC_CLIENT_TOATTR );
            if( it != attrs.end() )
            {
                _retries = StringUtils::toInt( val );
                _sleepInterval = StringUtils::toInt( (*it).second );
            }
            else
            {
                CBLOGERR(_logger,
                         NTEXT("RpcHttpClientTransport::init: can't find attributes to configure client communications parameters"));
            }
        }

        // setup the rpc address for this server
        String address;
        address = Net::getHostName();
        address += COLON;
        address += StringUtils::toString( _port );

        _transportAddress.setTransport( RPC_HTTP_NAME );
        _transportAddress.setAddress( address );

        // all is well set the initial state
        res = 0;
        _state = keRpcInitted;
    }

    if ( res == 0 )
    {
        RefCountedPtr<MyThdFn> wfn(new MyThdFn( *this, &RpcHttpTransport::myWorkerFunction ));
        pool->add( 1, (RefCountedPtr<iRunnable> &)wfn );

        // inititalize MasterServer Pointer
        ASSERT_D(masterServer != NULL);
        _masterServer = masterServer;
        _triggerEvent.reset();
        _startedEvent.reset();
    }

    return res;
}