71
71
ServerRequestAlternativeByteHandler* fServerRequestAlternativeByteHandler;
72
72
void* fServerRequestAlternativeByteHandlerClientData;
73
73
u_int8_t fStreamChannelId, fSizeByte1;
74
Boolean fReadErrorOccurred, fDeleteMyselfNext;
74
Boolean fReadErrorOccurred, fDeleteMyselfNext, fAreInReadHandlerLoop;
75
75
enum { AWAITING_DOLLAR, AWAITING_STREAM_CHANNEL_ID, AWAITING_SIZE1, AWAITING_SIZE2, AWAITING_PACKET_DATA } fTCPReadingState;
131
131
RTPInterface::~RTPInterface() {
132
stopNetworkReading();
132
133
delete fTCPStreams;
135
136
void RTPInterface::setStreamSocket(int sockNum,
136
137
unsigned char streamChannelId) {
137
138
fGS->removeAllDestinations();
139
envir().taskScheduler().disableBackgroundHandling(fGS->socketNum()); // turn off any reading on our datagram socket
140
fGS->reset(); // and close our datagram socket, because we won't be using it anymore
138
141
addStreamSocket(sockNum, streamChannelId);
188
::setServerRequestAlternativeByteHandler(int socketNum, ServerRequestAlternativeByteHandler* handler, void* clientData) {
189
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(envir(), socketNum);
190
void RTPInterface::setServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum,
191
ServerRequestAlternativeByteHandler* handler, void* clientData) {
192
SocketDescriptor* socketDescriptor = lookupSocketDescriptor(env, socketNum, False);
191
194
if (socketDescriptor != NULL) socketDescriptor->setServerRequestAlternativeByteHandler(handler, clientData);
197
void RTPInterface::clearServerRequestAlternativeByteHandler(UsageEnvironment& env, int socketNum) {
198
setServerRequestAlternativeByteHandler(env, socketNum, NULL, NULL);
195
201
Boolean RTPInterface::sendPacket(unsigned char* packet, unsigned packetSize) {
196
202
Boolean success = True; // we'll return False instead if any of the sends fail
277
283
envir().taskScheduler().turnOffBackgroundReadHandling(fGS->socketNum());
279
285
// Also turn off read handling on each of our TCP connections:
280
for (tcpStreamRecord* streams = fTCPStreams; streams != NULL;
281
streams = streams->fNext) {
286
for (tcpStreamRecord* streams = fTCPStreams; streams != NULL; streams = streams->fNext) {
282
287
deregisterSocket(envir(), streams->fStreamSocketNum, streams->fStreamChannelId);
343
348
:fEnv(env), fOurSocketNum(socketNum),
344
349
fSubChannelHashTable(HashTable::create(ONE_WORD_HASH_KEYS)),
345
350
fServerRequestAlternativeByteHandler(NULL), fServerRequestAlternativeByteHandlerClientData(NULL),
346
fReadErrorOccurred(False), fDeleteMyselfNext(False), fTCPReadingState(AWAITING_DOLLAR) {
351
fReadErrorOccurred(False), fDeleteMyselfNext(False), fAreInReadHandlerLoop(False), fTCPReadingState(AWAITING_DOLLAR) {
349
354
SocketDescriptor::~SocketDescriptor() {
350
355
fEnv.taskScheduler().turnOffBackgroundReadHandling(fOurSocketNum);
356
removeSocketDescription(fEnv, fOurSocketNum);
358
if (fSubChannelHashTable != NULL) {
359
// Remove knowledge of this socket from any "RTPInterface"s that are using it:
360
HashTable::Iterator* iter = HashTable::Iterator::create(*fSubChannelHashTable);
361
RTPInterface* rtpInterface;
364
while ((rtpInterface = (RTPInterface*)(iter->next(key))) != NULL) {
365
long streamChannelIdLong = (long)key;
366
unsigned char streamChannelId = (unsigned char)streamChannelIdLong;
368
rtpInterface->removeStreamSocket(fOurSocketNum, streamChannelId);
372
// Then remove the hash table entries themselves, and then remove the hash table:
373
while (fSubChannelHashTable->RemoveNext() != NULL) {}
374
delete fSubChannelHashTable;
351
378
if (fServerRequestAlternativeByteHandler != NULL) {
352
379
// Hack: Pass a special character to our alternative byte handler, to tell it that either
353
380
// - an error occurred when reading the TCP socket, or
355
382
u_int8_t specialChar = fReadErrorOccurred ? 0xFF : 0xFE;
356
383
(*fServerRequestAlternativeByteHandler)(fServerRequestAlternativeByteHandlerClientData, specialChar);
358
removeSocketDescription(fEnv, fOurSocketNum);
360
if (fSubChannelHashTable != NULL) {
361
while (fSubChannelHashTable->RemoveNext() != NULL) {} // remove the "RTPInterface"s from the table, but don't delete them
362
delete fSubChannelHashTable;
366
387
void SocketDescriptor::registerRTPInterface(unsigned char streamChannelId,
397
418
if (fSubChannelHashTable->IsEmpty()) {
398
419
// No more interfaces are using us, so it's curtains for us now:
399
fDeleteMyselfNext = True; // hack to cause ourself to be deleted from "tcpReadHandler()" below
420
if (fAreInReadHandlerLoop) {
421
fDeleteMyselfNext = True; // we can't delete ourself yet, but we'll do so from "tcpReadHandler()" below
403
428
void SocketDescriptor::tcpReadHandler(SocketDescriptor* socketDescriptor, int mask) {
404
429
// Call the read handler until it returns false, with a limit to avoid starving other sockets
405
430
unsigned count = 2000;
431
socketDescriptor->fAreInReadHandlerLoop = True;
406
432
while (!socketDescriptor->fDeleteMyselfNext && socketDescriptor->tcpReadHandler1(mask) && --count > 0) {}
433
socketDescriptor->fAreInReadHandlerLoop = False;
407
434
if (socketDescriptor->fDeleteMyselfNext) delete socketDescriptor;