explicit IntervalTimer(const Duration &duration) {
   tval_.it_interval = zeroTimeVal;
   // too small values are dangerous
   tval_.it_value =
       duration < resolution ? toTimeval(resolution) : toTimeval(duration);
   tval_.it_interval = toTimeval(resolution);  // in case event is missed
   BUNSAN_LOG_TRACE << "Setting timer for " << tval_.it_value.tv_sec << "s + "
                    << tval_.it_value.tv_usec << "us";
   system::unistd::setitimer(ITIMER_REAL, tval_);
 }
Esempio n. 2
0
void Config::load(boost::filesystem::path file)
{
    try
    {
        boost::program_options::store(boost::program_options::parse_config_file<char>(file.c_str(), desc), options);
    }
    catch (const std::exception& e)
    {
        CS_DIE("faild on read/parse config-file: " << file << "\n" << e.what());
    }
    boost::program_options::notify(options);

    pidFile = options["pid-file"].as<boost::filesystem::path>();

    usTcpNodelay = options["upstream-tcp-nodelay"].as<bool>();

    dsSendTimeout = toTimeval(options["downstream-send-timeout"].as<std::time_t>());
    usSendTimeout = toTimeval(options["upstream-send-timeout"].as<std::time_t>());

    drBufferSize = options["downstream-read-buffer-size"].as<std::size_t>() << 10;
    dwBufferSize = options["downstream-write-buffer-size"].as<std::size_t>() << 10;
    urBufferSize = options["upstream-read-buffer-size"].as<std::size_t>() << 10;
    uwBufferSize = options["upstream-write-buffer-size"].as<std::size_t>() << 10;

    usLinger = options["upstream-linger"].as<bool>();
    usLingerTimeout = options["upstream-linger-timeout"].as<int>();

    dwPendingInterval = options["downstream-write-pending-interval"].as<int>();
    uwPendingInterval = options["upstream-write-pending-interval"].as<int>();

    userPassTotalLen = options["username-password-total-max-len"].as<std::size_t>();

    ifaceName = options["iface-name"].as<std::string>();
    ifaceMtu = options["iface-mtu"].as<uint16_t>();

    CS_SAY(
        "loaded configs in [" << file.string() << "]:" << std::endl
        _PECAR_OUT_CONFIG_PROPERTY(programName)
        _PECAR_OUT_CONFIG_PROPERTY(usTcpNodelay)
        _PECAR_OUT_CONFIG_PROPERTY(drBufferSize)
        _PECAR_OUT_CONFIG_PROPERTY(dwBufferSize)
        _PECAR_OUT_CONFIG_PROPERTY(urBufferSize)
        _PECAR_OUT_CONFIG_PROPERTY(uwBufferSize)
        _PECAR_OUT_CONFIG_PROPERTY(dwPendingInterval)
        _PECAR_OUT_CONFIG_PROPERTY(uwPendingInterval)
        _PECAR_OUT_CONFIG_PROPERTY(usLinger)
        _PECAR_OUT_CONFIG_PROPERTY(usLingerTimeout)
        _PECAR_OUT_CONFIG_PROPERTY(userPassTotalLen)
        _PECAR_OUT_CONFIG_PROPERTY(ifaceName)
        _PECAR_OUT_CONFIG_PROPERTY(ifaceMtu)
    );
}
Esempio n. 3
0
static error waitUntilReady(const SocketFD& fd,
        fd_set* readfds, fd_set* writefds, fd_set* exceptfds,
        int64_t timeoutMilliseconds) {
    if (readfds != nullptr) {
        FD_ZERO(readfds);
        FD_SET(fd, readfds);
    }
    if (writefds != nullptr) {
        FD_ZERO(writefds);
        FD_SET(fd, writefds);
    }
    if (exceptfds != nullptr) {
        FD_ZERO(exceptfds);
        FD_SET(fd, exceptfds);
    }
    struct timeval timeout;
    toTimeval(timeoutMilliseconds, &timeout);

    int result = select(0, readfds, writefds, exceptfds, &timeout);
    if (result == SOCKET_ERROR) {
        return error::wrap(etype::os, WSAGetLastError());
    } else if (result == 0) {
        return error::timedout;
    } else {
        int soErr = 0;
        int optlen = sizeof(soErr);
        getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*) &soErr, &optlen);
        if (soErr != 0) {
            return error::wrap(etype::os, soErr);
        }
        return error::nil;
    }
}
Esempio n. 4
0
	/** Convert time into a string
         * \param resolution Resolution which the string should present
         * \param mainFormat Main format to use -- this is passed to strftime and appended by ':' plus the
         *     below seconds resolution if requested by the resolution argument
         **/
	std::string toString(base::Time::Resolution resolution = Microseconds, const std::string& mainFormat = "%Y%m%d-%H:%M:%S") const
	{
            struct timeval tv = toTimeval();
            int uSecs = tv.tv_usec;

	    time_t when = tv.tv_sec;
	    struct tm *tm = localtime(&when); 

            char time[50];
            strftime(time,50, mainFormat.c_str(), tm);

            char buffer[57];
            switch(resolution)
            {
                case Seconds:
                    return std::string(time);
                case Milliseconds:
                    sprintf(buffer,"%s:%03d", time, (int) (uSecs/1000.0));
                    break;
                case Microseconds:
                    sprintf(buffer,"%s:%06d", time, uSecs);
                    break;
                default: 
                    assert(-1);
            }

	    return std::string(buffer);
	}
Esempio n. 5
0
static jboolean OSNetworkSystem_selectImpl(JNIEnv* env, jclass,
        jobjectArray readFDArray, jobjectArray writeFDArray, jint countReadC,
        jint countWriteC, jintArray outFlags, jlong timeoutMs) {

    // Initialize the fd_sets.
    int maxFd = -1;
    fd_set readFds;
    fd_set writeFds;
    FD_ZERO(&readFds);
    FD_ZERO(&writeFds);
    bool initialized = initFdSet(env, readFDArray, countReadC, &readFds, &maxFd) &&
                       initFdSet(env, writeFDArray, countWriteC, &writeFds, &maxFd);
    if (!initialized) {
        return -1;
    }

    // Initialize the timeout, if any.
    timeval tv;
    timeval* tvp = NULL;
    if (timeoutMs >= 0) {
        tv = toTimeval(timeoutMs);
        tvp = &tv;
    }

    // Perform the select.
    int result = select(maxFd + 1, &readFds, &writeFds, NULL, tvp);
    if (result == 0) {
        // Timeout.
        return JNI_FALSE;
    } else if (result == -1) {
        // Error.
        if (errno == EINTR) {
            return JNI_FALSE;
        } else {
            jniThrowSocketException(env, errno);
            return JNI_FALSE;
        }
    }

    // Translate the result into the int[] we're supposed to fill in.
    ScopedIntArrayRW flagArray(env, outFlags);
    if (flagArray.get() == NULL) {
        return JNI_FALSE;
    }
    return translateFdSet(env, readFDArray, countReadC, readFds, flagArray.get(), 0, SOCKET_OP_READ) &&
            translateFdSet(env, writeFDArray, countWriteC, writeFds, flagArray.get(), countReadC, SOCKET_OP_WRITE);
}
Esempio n. 6
0
    // Returns 0 if we're connected; -EINPROGRESS if we're still hopeful, -errno if we've failed.
    // 'timeout' the timeout in milliseconds. If timeout is negative, perform a blocking operation.
    int isConnected(int fd, int timeout) {
        timeval passedTimeout(toTimeval(timeout));

        // Initialize the fd sets for the select.
        fd_set readSet;
        fd_set writeSet;
        FD_ZERO(&readSet);
        FD_ZERO(&writeSet);
        FD_SET(fd, &readSet);
        FD_SET(fd, &writeSet);

        int nfds = fd + 1;
        timeval* tp = timeout >= 0 ? &passedTimeout : NULL;
        int rc = select(nfds, &readSet, &writeSet, NULL, tp);
        if (rc == -1) {
            if (errno == EINTR) {
                // We can't trivially retry a select with TEMP_FAILURE_RETRY, so punt and ask the
                // caller to try again.
                return -EINPROGRESS;
            }
            return -errno;
        }

        // If the fd is just in the write set, we're connected.
        if (FD_ISSET(fd, &writeSet) && !FD_ISSET(fd, &readSet)) {
            return 0;
        }

        // If the fd is in both the read and write set, there was an error.
        if (FD_ISSET(fd, &readSet) || FD_ISSET(fd, &writeSet)) {
            // Get the pending error.
            int error = 0;
            socklen_t errorLen = sizeof(error);
            if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &errorLen) == -1) {
                return -errno; // Couldn't get the real error, so report why not.
            }
            return -error;
        }

        // Timeout expired.
        return -EINPROGRESS;
    }
Esempio n. 7
0
static int handle_client(int client_fd)
{
	int status;
	size_t size, nitems;
	FILE *serial_file;
	char buf[1024];	/* buffer for serial IO */
	CapCommand cmd;
	char ruser[64], rhost[64], realhost[64];
	double rate, time;
	fd_set rd_fds;
	struct timeval timeout, now, *timeoutPtr;
	int    recording = 0;
	double recordNow    = 0.;
	double recordNext   = 0.;
	double recordPeriod = 0.;
	double recordDelta  = 0.;
#ifdef _WIN32
	int ms;
#endif

	while (1)
	{
		FD_ZERO(&rd_fds);
		FD_SET(client_fd, &rd_fds);

		if ( !recording ) {
			timeoutPtr = NULL;
		} else {
			/* record and schedule the next recording */
#ifdef LINUX
			gettimeofday(&now, NULL);
#else
			gettimeofday(&now);
#endif
			recordNow   = toDouble(now);
			if ( recordNext == 0.0 ) /* The first record */
				recordNext = recordNow;

			while ( recordNext <= recordNow ) {
				get_data(client_fd);
				recordNext = recordNext + recordPeriod;
			}
			
			timeout = toTimeval( recordNext - recordNow );
			timeoutPtr = &timeout;
		}

		/*
		 * wait for commands or a timeout
		 */
#ifndef _WIN32
		status = select(FD_SETSIZE, &rd_fds, NULL, NULL, timeoutPtr);
#else
		/* Should really use CapWaitTimeout when possible */
		ms = -1;
		if (timeoutPtr)
			ms = timeoutPtr->tv_sec*1000 + timeoutPtr->tv_usec/1000;
		status = CapWaitTimeout(client_fd, ms);
#endif


		if (status < 0 ) {
			if (errno == EINTR) {
				/* Ignore signals and try again */
				continue;
			}

			/* Otherwise, give a fatal error message */
			CapError(client_fd, CAP_SEV_FATAL, gProgramName, "select failed");
			CapError(client_fd, CAP_SEV_FATAL, "select", NULL);
			exit(1);
		}
		else if (status == 0) {
			/* Try again */
			continue;
		}

		/* There is data on the client file descriptor */
		cmd = CapGetCommand(client_fd);
		switch (cmd) {
		case CAP_CMD_QUIT:
			return 0;

		case CAP_CMD_AUTHORIZE:
			status = CapGetAuthInfo(client_fd, ruser, rhost, realhost);
			if (status < 0)
			{
				return -1;
			}

			/*
			 * If user@host is not authorized to use this server then:
			 *
			 * status = CapAuthorize(client_fd, 0);
			 */
			status = CapAuthorize(client_fd, 1);
			break;

		case CAP_CMD_INIT:	/* Initial client/server handshake */
			status = CapInitialize(client_fd, gProgramName);
			break;

		case CAP_CMD_VERSION:	/* Send version information */
			status = CapVersion(client_fd, gProgramName, "1.0",
								"Extern server (example) - v1.0");
			break;

		case CAP_CMD_INFO:
			if (NULL == gChannels)
			{
				/* Only create the channel data once */
				gChannels = create_channels(gConfigFile, client_fd);
				if ( NULL == gChannels)
				{
					status = CapError(client_fd, CAP_SEV_ERROR, 
									  gProgramName,
									  "Missing or empty config file");  
				}
			}
			/* Return the recording information. gMaxRecordRate <= 0.
			 * says recording is not supported
			 */
			{
				size_t buf_size = 0;
				if ( 0. < gMaxRecordRate) 
					buf_size = INT_MAX;
				status = CapInfo(client_fd, gMinRecordRate, 
								 gMaxRecordRate, gDefRecordRate, 
								 buf_size, 1);
			}
			break;
	  
		case CAP_CMD_DATA:	/* Send frame data */
			if (!recording )
				get_data(client_fd);
			status = CapData(client_fd);
			break;


		case CAP_CMD_START_RECORD:	/* Start recording */
			rate = CapGetRequestedRecordRate(client_fd);
			size = CapGetRequestedRecordSize(client_fd);

			/* 
			 * Set up for recording operations
			 */
			if (rate < gMinRecordRate ) 
				rate = gMinRecordRate;
			else if (rate > gMaxRecordRate ) 
				rate = gMaxRecordRate;

			status = CapStartRecord(client_fd, rate, size);
			if (status != -1)
			{
				recordPeriod = 1.0 / rate;
				recordNext   = 0.;
				recording = 1;
			}
			break;

		case CAP_CMD_STOP_RECORD:		/* Stop recording */
			status = CapStopRecord(client_fd);
			recording = 0;
			break;

		default:			/* Ignore unknown commands */
			status = CapError(client_fd, CAP_SEV_ERROR, gProgramName,
							  "Unknown server command.");
			break;
		}

		if (status < 0)
		{
			return -1;
		}
		
	}

	/* return 0; */
}
Esempio n. 8
0
static void OSNetworkSystem_accept(JNIEnv* env, jobject, jobject serverFileDescriptor,
        jobject newSocket, jobject clientFileDescriptor) {

    if (newSocket == NULL) {
        jniThrowNullPointerException(env, NULL);
        return;
    }

    NetFd serverFd(env, serverFileDescriptor);
    if (serverFd.isClosed()) {
        return;
    }

    sockaddr_storage ss;
    socklen_t addrLen = sizeof(ss);
    sockaddr* sa = reinterpret_cast<sockaddr*>(&ss);

    int clientFd;
    {
        int intFd = serverFd.get();
        AsynchronousSocketCloseMonitor monitor(intFd);
        clientFd = NET_FAILURE_RETRY(serverFd, accept(intFd, sa, &addrLen));
    }
    if (env->ExceptionOccurred()) {
        return;
    }
    if (clientFd == -1) {
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            jniThrowSocketTimeoutException(env, errno);
        } else {
            jniThrowSocketException(env, errno);
        }
        return;
    }

    // Reset the inherited read timeout to the Java-specified default of 0.
    timeval timeout(toTimeval(0));
    int rc = setsockopt(clientFd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
    if (rc == -1) {
        LOGE("couldn't reset SO_RCVTIMEO on accepted socket fd %i: %s", clientFd, strerror(errno));
        jniThrowSocketException(env, errno);
    }

    /*
     * For network sockets, put the peer address and port in instance variables.
     * We don't bother to do this for UNIX domain sockets, since most peers are
     * anonymous anyway.
     */
    if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
        // Remote address and port.
        jobject remoteAddress = socketAddressToInetAddress(env, &ss);
        if (remoteAddress == NULL) {
            close(clientFd);
            return;
        }
        int remotePort = getSocketAddressPort(&ss);
        env->SetObjectField(newSocket, gCachedFields.socketimpl_address, remoteAddress);
        env->SetIntField(newSocket, gCachedFields.socketimpl_port, remotePort);

        // Local port.
        memset(&ss, 0, addrLen);
        int rc = getsockname(clientFd, sa, &addrLen);
        if (rc == -1) {
            close(clientFd);
            jniThrowSocketException(env, errno);
            return;
        }
        int localPort = getSocketAddressPort(&ss);
        env->SetIntField(newSocket, gCachedFields.socketimpl_localport, localPort);
    }

    jniSetFileDescriptorOfFD(env, clientFileDescriptor, clientFd);
}
Esempio n. 9
0
static void OSNetworkSystem_setSocketOption(JNIEnv* env, jobject, jobject fileDescriptor, jint option, jobject optVal) {
    NetFd fd(env, fileDescriptor);
    if (fd.isClosed()) {
        return;
    }

    int intVal;
    bool wasBoolean = false;
    if (env->IsInstanceOf(optVal, JniConstants::integerClass)) {
        intVal = (int) env->GetIntField(optVal, gCachedFields.integer_class_value);
    } else if (env->IsInstanceOf(optVal, JniConstants::booleanClass)) {
        intVal = (int) env->GetBooleanField(optVal, gCachedFields.boolean_class_value);
        wasBoolean = true;
    } else if (env->IsInstanceOf(optVal, JniConstants::inetAddressClass)) {
        // We use optVal directly as an InetAddress for IP_MULTICAST_IF.
    } else if (env->IsInstanceOf(optVal, JniConstants::multicastGroupRequestClass)) {
        // We use optVal directly as a MulticastGroupRequest for MCAST_JOIN_GROUP/MCAST_LEAVE_GROUP.
    } else {
        jniThrowSocketException(env, EINVAL);
        return;
    }

    int family = getSocketAddressFamily(fd.get());
    if (family != AF_INET && family != AF_INET6) {
        jniThrowSocketException(env, EAFNOSUPPORT);
        return;
    }

    // Since we expect to have a AF_INET6 socket even if we're communicating via IPv4, we always
    // set the IPPROTO_IP options. As long as we fall back to creating IPv4 sockets if creating
    // an IPv6 socket fails, we need to make setting the IPPROTO_IPV6 options conditional.
    switch (option) {
    case JAVASOCKOPT_IP_TOS:
        setSocketOption(env, fd, IPPROTO_IP, IP_TOS, &intVal);
        if (family == AF_INET6) {
            setSocketOption(env, fd, IPPROTO_IPV6, IPV6_TCLASS, &intVal);
        }
        return;
    case JAVASOCKOPT_SO_BROADCAST:
        setSocketOption(env, fd, SOL_SOCKET, SO_BROADCAST, &intVal);
        return;
    case JAVASOCKOPT_SO_KEEPALIVE:
        setSocketOption(env, fd, SOL_SOCKET, SO_KEEPALIVE, &intVal);
        return;
    case JAVASOCKOPT_SO_LINGER:
        {
            linger l;
            l.l_onoff = !wasBoolean;
            l.l_linger = intVal <= 65535 ? intVal : 65535;
            setSocketOption(env, fd, SOL_SOCKET, SO_LINGER, &l);
            return;
        }
    case JAVASOCKOPT_SO_OOBINLINE:
        setSocketOption(env, fd, SOL_SOCKET, SO_OOBINLINE, &intVal);
        return;
    case JAVASOCKOPT_SO_RCVBUF:
        setSocketOption(env, fd, SOL_SOCKET, SO_RCVBUF, &intVal);
        return;
    case JAVASOCKOPT_SO_REUSEADDR:
        setSocketOption(env, fd, SOL_SOCKET, SO_REUSEADDR, &intVal);
        return;
    case JAVASOCKOPT_SO_SNDBUF:
        setSocketOption(env, fd, SOL_SOCKET, SO_SNDBUF, &intVal);
        return;
    case JAVASOCKOPT_SO_TIMEOUT:
        {
            timeval timeout(toTimeval(intVal));
            setSocketOption(env, fd, SOL_SOCKET, SO_RCVTIMEO, &timeout);
            return;
        }
    case JAVASOCKOPT_TCP_NODELAY:
        setSocketOption(env, fd, IPPROTO_TCP, TCP_NODELAY, &intVal);
        return;
#ifdef ENABLE_MULTICAST
    case JAVASOCKOPT_MCAST_JOIN_GROUP:
        mcastJoinLeaveGroup(env, fd.get(), optVal, true);
        return;
    case JAVASOCKOPT_MCAST_LEAVE_GROUP:
        mcastJoinLeaveGroup(env, fd.get(), optVal, false);
        return;
    case JAVASOCKOPT_IP_MULTICAST_IF:
        {
            sockaddr_storage sockVal;
            if (!env->IsInstanceOf(optVal, JniConstants::inetAddressClass) ||
                    !inetAddressToSocketAddress(env, optVal, 0, &sockVal)) {
                return;
            }
            // This call is IPv4 only. The socket may be IPv6, but the address
            // that identifies the interface to join must be an IPv4 address.
            if (sockVal.ss_family != AF_INET) {
                jniThrowSocketException(env, EAFNOSUPPORT);
                return;
            }
            ip_mreqn mcast_req;
            memset(&mcast_req, 0, sizeof(mcast_req));
            mcast_req.imr_address = reinterpret_cast<sockaddr_in*>(&sockVal)->sin_addr;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &mcast_req);
            return;
        }
    case JAVASOCKOPT_IP_MULTICAST_IF2:
        // TODO: is this right? should we unconditionally set the IPPROTO_IP state in case
        // we have an IPv6 socket communicating via IPv4?
        if (family == AF_INET) {
            // IP_MULTICAST_IF expects a pointer to an ip_mreqn struct.
            ip_mreqn multicastRequest;
            memset(&multicastRequest, 0, sizeof(multicastRequest));
            multicastRequest.imr_ifindex = intVal;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_IF, &multicastRequest);
        } else {
            // IPV6_MULTICAST_IF expects a pointer to an integer.
            setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &intVal);
        }
        return;
    case JAVASOCKOPT_MULTICAST_TTL:
        {
            // Although IPv6 was cleaned up to use int, and IPv4 non-multicast TTL uses int,
            // IPv4 multicast TTL uses a byte.
            u_char ttl = intVal;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_TTL, &ttl);
            if (family == AF_INET6) {
                setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &intVal);
            }
            return;
        }
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        {
            // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
            u_char loopback = intVal;
            setSocketOption(env, fd, IPPROTO_IP, IP_MULTICAST_LOOP, &loopback);
            if (family == AF_INET6) {
                setSocketOption(env, fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &intVal);
            }
            return;
        }
#else
    case JAVASOCKOPT_MULTICAST_TTL:
    case JAVASOCKOPT_MCAST_JOIN_GROUP:
    case JAVASOCKOPT_MCAST_LEAVE_GROUP:
    case JAVASOCKOPT_IP_MULTICAST_IF:
    case JAVASOCKOPT_IP_MULTICAST_IF2:
    case JAVASOCKOPT_IP_MULTICAST_LOOP:
        jniThrowException(env, "java/lang/UnsupportedOperationException", NULL);
        return;
#endif // def ENABLE_MULTICAST
    default:
        jniThrowSocketException(env, ENOPROTOOPT);
    }
}
Esempio n. 10
0
main( int argc, char *argv[] ) {
	
	double playNow    = 0;
	double playNext   = 0;
	double playPeriod = 1./30.;
	FILE   *dataFile  = NULL;

	parseArgs( argc, argv);

	playPeriod = 1./ gPlayFreq;

	dataFile = fopen(gDataPath, "r");
	if ( NULL == dataFile ) {
		fprintf(stderr,
				"%s: could not open file %s", gProgramName, gDataPath);
		exit(1);
	}

	gBuffer = malloc(gBufferSize);
	if ( NULL == gBuffer ) {
		fprintf(stderr,
				"%s: out of memory, -b %d failed", gProgramName, gBufferSize);
		exit(1);
	}

	strcpy(gBuffer,"");



	while (1) {
		struct timeval timeout, now;
#ifdef LINUX
	    gettimeofday(&now,NULL);
#else
		gettimeofday(&now);
#endif            
		playNow   = toDouble(now);
		if ( playNext == 0.0 ) /* The first record */
			playNext = playNow;

		while ( playNext <= playNow ) {
			if ( NULL == fgets(gBuffer, gBufferSize, dataFile ) ) {
				rewind( dataFile); 
				if ( NULL == fgets(gBuffer, gBufferSize, dataFile ) ) {
					fprintf(stderr, "%s: file read failed", 
							gProgramName);
					exit(1);
				}
			}
				
			printf( "%s", gBuffer );				
			playNext = playNext + playPeriod;
		}
		fflush(stdout);
			
		/*
		 * wait for commands or a timeout
		 */
		timeout = toTimeval( playNext - playNow );
		select(FD_SETSIZE, NULL, NULL, NULL, &timeout);

	}

}