Example #1
0
void NetManager::ReadService()
{
	// intro section
	char dummy;

	// loop section
	while (readstate.running)
	{
		// block section
		CompileReadPollList(); // stores data in readstate.polllist
		int i = WaitForRead(); // reads data in readstate.polllist and returns the index of the first file descriptor it finds

		// service section
		if (i == 0) // if the service pipe has data
		{
			readstate.servicelock.Wait(readstate.readmutex); // wait for service to finish 
			read(readstate.servicepipe_in, &dummy, 1);
			continue;
		}
		else if (i < 0) continue;
		
		// general section
		ReadIncomingData(i - 1);
	}
	return;
}
Example #2
0
void
ConsoleSetupProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    ConsoleInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };
    int block = 1;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }

    /*
     * Look to see if any events are already pending. If they are, poll.
     */

    for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
		block = 0;
	    }
	}
	if (infoPtr->watchMask & TCL_READABLE) {
	    if (WaitForRead(infoPtr, 0) >= 0) {
		block = 0;
	    }
	}
    }
    if (!block) {
	Tcl_SetMaxBlockTime(&blockTime);
    }
}
Example #3
0
static void
ConsoleCheckProc(
    ClientData data,		/* Not used. */
    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
{
    ConsoleInfo *infoPtr;
    int needEvent;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }

    /*
     * Queue events for any ready consoles that don't already have events
     * queued.
     */

    for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->flags & CONSOLE_PENDING) {
	    continue;
	}

	/*
	 * Queue an event if the console is signaled for reading or writing.
	 */

	needEvent = 0;
	if (infoPtr->watchMask & TCL_WRITABLE) {
	    if (WaitForSingleObject(infoPtr->writer.readyEvent,
		    0) != WAIT_TIMEOUT) {
		needEvent = 1;
	    }
	}

	if (infoPtr->watchMask & TCL_READABLE) {
	    if (WaitForRead(infoPtr, 0) >= 0) {
		needEvent = 1;
	    }
	}

	if (needEvent) {
	    ConsoleEvent *evPtr = ckalloc(sizeof(ConsoleEvent));

	    infoPtr->flags |= CONSOLE_PENDING;
	    evPtr->header.proc = ConsoleEventProc;
	    evPtr->infoPtr = infoPtr;
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	}
    }
}
Example #4
0
Socket* UnixSocket::Accept() {
  socklen_t clilen;
  struct sockaddr_in cli_addr;
  clilen = sizeof(cli_addr);

  if (!WaitForRead(500)) {
    return 0;
  }

  int client = accept(mSocket, 
                      (struct sockaddr *) &cli_addr, 
                      &clilen);
  if (client < 0)  {
    perror("ERROR on accept");
    close(mSocket);
    return 0;
  }
  return new UnixSocket(client);
}
Example #5
0
static int
ConsoleEventProc(
    Tcl_Event *evPtr,		/* Event to service. */
    int flags)			/* Flags that indicate what events to handle,
				 * such as TCL_FILE_EVENTS. */
{
    ConsoleEvent *consoleEvPtr = (ConsoleEvent *)evPtr;
    ConsoleInfo *infoPtr;
    int mask;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Search through the list of watched consoles for the one whose handle
     * matches the event. We do this rather than simply dereferencing the
     * handle in the event so that consoles can be deleted while the event is
     * in the queue.
     */

    for (infoPtr = tsdPtr->firstConsolePtr; infoPtr != NULL;
	    infoPtr = infoPtr->nextPtr) {
	if (consoleEvPtr->infoPtr == infoPtr) {
	    infoPtr->flags &= ~(CONSOLE_PENDING);
	    break;
	}
    }

    /*
     * Remove stale events.
     */

    if (!infoPtr) {
	return 1;
    }

    /*
     * Check to see if the console is readable. Note that we can't tell if a
     * console is writable, so we always report it as being writable unless we
     * have detected EOF.
     */

    mask = 0;
    if (infoPtr->watchMask & TCL_WRITABLE) {
	if (WaitForSingleObject(infoPtr->writable, 0) != WAIT_TIMEOUT) {
	    mask = TCL_WRITABLE;
	}
    }

    if (infoPtr->watchMask & TCL_READABLE) {
	if (WaitForRead(infoPtr, 0) >= 0) {
	    if (infoPtr->readFlags & CONSOLE_EOF) {
		mask = TCL_READABLE;
	    } else {
		mask |= TCL_READABLE;
	    }
	}
    }

    /*
     * Inform the channel of the events.
     */

    Tcl_NotifyChannel(infoPtr->channel, infoPtr->watchMask & mask);
    return 1;
}
Example #6
0
static int
ConsoleInputProc(
    ClientData instanceData,	/* Console state. */
    char *buf,			/* Where to store data read. */
    int bufSize,		/* How much space is available in the
				 * buffer? */
    int *errorCode)		/* Where to store error code. */
{
    ConsoleInfo *infoPtr = (ConsoleInfo *) instanceData;
    DWORD count, bytesRead = 0;
    int result;

    *errorCode = 0;

    /*
     * Synchronize with the reader thread.
     */

    result = WaitForRead(infoPtr, (infoPtr->flags & CONSOLE_ASYNC) ? 0 : 1);

    /*
     * If an error occurred, return immediately.
     */

    if (result == -1) {
	*errorCode = errno;
	return -1;
    }

    if (infoPtr->readFlags & CONSOLE_BUFFERED) {
	/*
	 * Data is stored in the buffer.
	 */

	if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], (size_t) bufSize);
	    bytesRead = bufSize;
	    infoPtr->offset += bufSize;
	} else {
	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], (size_t) bufSize);
	    bytesRead = infoPtr->bytesRead - infoPtr->offset;

	    /*
	     * Reset the buffer
	     */

	    infoPtr->readFlags &= ~CONSOLE_BUFFERED;
	    infoPtr->offset = 0;
	}

	return bytesRead;
    }

    /*
     * Attempt to read bufSize bytes. The read will return immediately if
     * there is any data available. Otherwise it will block until at least one
     * byte is available or an EOF occurs.
     */

    if (readConsoleBytes(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize, &count)
	    == TRUE) {
	buf[count] = '\0';
	return count;
    }

    return -1;
}
Example #7
0
bool SendSourceTable::Call(bool status)
///////////////////////////////////////////////////////////////////////////////
// Call continues sending the SRC table to the client when an event occurs
///////////////////////////////////////////////////////////////////////////////
{
    // If problems sending table, then quit
    if (status != OK)
        return Error("Was unable to send the source table\n");

    // Repeat for each mount point [0..n-1], 
    //     with an added header [-1] and trailer [n] and shutdown [n+1]
    for (;Next <= mounts.MaxMounts; Next++) {

        // Finish sending the previous buffer if any
        while (Actual < Len) {
            ssize_t actual;
            if (conn->Write(Buf+Actual, Len-Actual, actual) != OK || actual < 0)
                return Error("Write problems sending the Source Table\n");

            Actual += actual;
            if (Actual < Len)
                return WaitForRead(conn.get(), 10000);
        }

        // Process according to which record we are at.
        // Case: -1 -- Header record  
        if (Next == -1) {
           
            // Figure out how much characters in message
            size_t total = 0;
            for (int i=0; i<mounts.MaxMounts; i++)
                if (mounts[i].State == MOUNTED)
                    total += strlen(mounts.Mounts[i].STR);   // Add each mounted STR
            total += 2; // Add final /r/n

            // NOTE: if streams are mounted or dismounted while sending the table, 
            //       then the count will be invalid.
            //       We will assume it doesn't matter for now.

            // Build a buffer containing the message header
            snprintf(Header, sizeof(Header), "SOURCETABLE 200 OK\r\n"
                                             "Server: "CASTER_SW"/1.0\r\n"
                                             "Content-Type: text/plain\r\n"
                                             "Content-Length: %d\r\n"
                                             "\r\n", total);

            // Start Sending the header
            Buf = (byte *)Header; Len = strlen(Header); Actual = 0;
        }

        // Case: 0..n-1.  Sending an STR record
        else if (Next < mounts.MaxMounts) {

            // if Mounted, then send STR record
            if (mounts[Next].State == MOUNTED) {
                Buf = (byte *)mounts[Next].STR; Len = strlen(mounts[Next].STR); Actual = 0;
            }
        }

        // Case: n.  Send the trailing "\r\n"
        else if (Next == mounts.MaxMounts) {
            Buf = (const byte *)"\r\n"; Len = 2; Actual = 0;
        }
    }

    // We are done. Tell Dispatcher we can be deleted.
    return !OK;
}
Example #8
0
bool FSocketRaw::WaitForReadWrite( int WaitTime )
{
	return WaitForRead( WaitTime ) || WaitForWrite(WaitTime);
}
Example #9
0
static int
ConsoleInputProc(
    ClientData instanceData,	/* Console state. */
    char *buf,			/* Where to store data read. */
    int bufSize,		/* How much space is available in the
				 * buffer? */
    int *errorCode)		/* Where to store error code. */
{
    ConsoleInfo *infoPtr = instanceData;
    DWORD count, bytesRead = 0;
    int result;

    *errorCode = 0;

    /*
     * Synchronize with the reader thread.
     */

    result = WaitForRead(infoPtr, (infoPtr->flags & CONSOLE_ASYNC) ? 0 : 1);

    /*
     * If an error occurred, return immediately.
     */

    if (result == -1) {
	*errorCode = errno;
	return -1;
    }

    if (infoPtr->readFlags & CONSOLE_BUFFERED) {
	/*
	 * Data is stored in the buffer.
	 */

	if (bufSize < (infoPtr->bytesRead - infoPtr->offset)) {
	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], (size_t) bufSize);
	    bytesRead = bufSize;
	    infoPtr->offset += bufSize;
	} else {
	    memcpy(buf, &infoPtr->buffer[infoPtr->offset], (size_t) bufSize);
	    bytesRead = infoPtr->bytesRead - infoPtr->offset;

	    /*
	     * Reset the buffer.
	     */

	    infoPtr->readFlags &= ~CONSOLE_BUFFERED;
	    infoPtr->offset = 0;
	}

	return bytesRead;
    }

    /*
     * Attempt to read bufSize bytes. The read will return immediately if
     * there is any data available. Otherwise it will block until at least one
     * byte is available or an EOF occurs.
     */

    if (ReadConsoleBytes(infoPtr->handle, (LPVOID) buf, (DWORD) bufSize,
	    &count) == TRUE) {
	/*
	 * TODO: This potentially writes beyond the limits specified
	 * by the caller.  In practice this is harmless, since all writes
	 * are into ChannelBuffers, and those have padding, but still
	 * ought to remove this, unless some Windows wizard can give
	 * a reason not to.
	 */
	buf[count] = '\0';
	return count;
    }

    return -1;
}