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; }
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); } }
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); } } }
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); }
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; }
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; }
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; }
bool FSocketRaw::WaitForReadWrite( int WaitTime ) { return WaitForRead( WaitTime ) || WaitForWrite(WaitTime); }
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; }