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; } } }
/*! * 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; }