void StressTest(OSCQueue q) { int i,j; myObj *item; printf("\n\nStress Test...\n\n"); for (i = 1; i < NUM_OBJS; ++i) { objects[i].timetag = rand(); objects[i].data = "stress test"; if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[i])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } if (i % 13 == 0) { item = (myObj *) OSCQueueRemoveEarliest(q); printf("First earliest: %llu\n", item->timetag); item = (myObj *) OSCQueueRemoveEarliest(q); printf("Second earliest: %llu\n", item->timetag); item = (myObj *) OSCQueueRemoveEarliest(q); printf("Third earliest: %llu\n\n", item->timetag); } } while (OSCQueueEarliestTimeTag(q) != OSCTT_BiggestPossibleTimeTag()) { item = (myObj *) OSCQueueRemoveEarliest(q); printf("next from queue: %llu\n", item->timetag); } }
Boolean OSCScheduleInternalMessages(OSCTimeTag when, int numMessages, char **addresses, int *arglens, void **args) { int i, bufSizeNeeded, paddedStrLen; OSCPacketBuffer p; queuedData *qd, *scan; char *bufPtr; char *oldBufPtr; /* Figure out how big of a buffer we'll need to hold this huge bundle. We don't store the "#bundle" string or the time tag, just the 4-byte size counts, the addresses, possible extra null padding for the addresses, and the arguments. */ bufSizeNeeded = 0; for (i = 0; i < numMessages; ++i) { bufSizeNeeded += 4 + OSCPaddedStrlen(addresses[i]) + arglens[i]; } if (bufSizeNeeded > OSCGetReceiveBufferSize()) { return FALSE; } /* Now try to allocate the data objects to hold these messages */ qd = AllocQD(); if (qd == 0) return FALSE; p = OSCAllocPacketBuffer(); if (p == 0) { FreeQD(qd); return FALSE; } /* Now fill in the buffer with a fake #bundle message. This is almost like putting a real #bundle message in the buffer and then calling OSCAcceptPacket, except that we save a little time and memory by not writing "#bundle" or the time tag, and by pre-parsing the messages a little. Thus, this code duplicates a lot of what's in InsertBundleOrMessage() */ bufPtr = p->buf; for (i = 0; i < numMessages; ++i) { /* First the size count of this bundle element */ *((int4 *) bufPtr) = OSCPaddedStrlen(addresses[i]) + arglens[i]; bufPtr += sizeof(int4); /* Then the address */ bufPtr = OSCPaddedStrcpy(bufPtr, addresses[i]); /* Then the arguments */ memcpy(bufPtr, args[i], arglens[i]); bufPtr += arglens[i]; } #ifdef PARANOID if (bufPtr != p->buf+bufSizeNeeded) { fatal_error("OSCScheduleInternalMessages: internal error"); } #endif /* Fill in the rest of the packet fields */ p->n = bufSizeNeeded; p->returnAddrOK = FALSE; PacketAddRef(p); /* Now fill in the queuedData object */ qd->timetag = when; qd->myPacket = p; qd->type = BUNDLE; qd->data.bundle.length = bufSizeNeeded; qd->data.bundle.bytes = p->buf; /* Now we can put it into the scheduling queue. */ OSCQueueInsert(globals.TheQueue, (OSCSchedulableObject) qd); return TRUE; }
static void InsertBundleOrMessage(char *buf, int n, OSCPacketBuffer packet, OSCTimeTag enclosingTimeTag) { Boolean IsBundle; queuedData *qd; /* We add the reference first thing so in case any of the upcoming potential failure situations come we can call PacketRemoveRef, thereby freeing the packet if necessary. */ PacketAddRef(packet); #ifdef PARANOID if ((n % 4) != 0) { OSCProblem("OSC message or bundle size (%d bytes) not a multiple of 4.", n); DropMessage(buf, n, packet) PacketRemoveRef(packet); return; } #endif if ((n >= 8) && (strncmp(buf, "#bundle", 8) == 0)) { IsBundle = TRUE; if (n < 16) { OSCProblem("Bundle message too small (%d bytes) for time tag.", n); DropBundle(buf, n, packet); PacketRemoveRef(packet); return; } } else { IsBundle = FALSE; } qd = AllocQD(); if (qd == 0) { OSCProblem("Not enough memory for queued data!"); DropBundle(buf, n, packet); PacketRemoveRef(packet); return; } qd->myPacket = packet; qd->type = IsBundle ? BUNDLE : MESSAGE; if (IsBundle) { /* Be careful of 8-byte alignment when copying the time tag. Here's a good way to get a bus error when buf happens not to be 8-byte aligned: qd->timetag = *((OSCTimeTag *)(buf+8)); */ memcpy(&(qd->timetag), buf+8, sizeof(OSCTimeTag)); if (OSCTT_Compare(qd->timetag, enclosingTimeTag) < 0) { OSCProblem("Time tag of sub-bundle is before time tag of enclosing bundle."); DropBundle(buf, n, packet); PacketRemoveRef(packet); FreeQD(qd); return; } qd->data.bundle.bytes = buf + 16; qd->data.bundle.length = n - 16; } else { qd->timetag = enclosingTimeTag; qd->data.message.messageName = buf; qd->data.message.length = n; qd->data.message.callbacks = NOT_DISPATCHED_YET; } OSCQueueInsert(globals.TheQueue, (OSCSchedulableObject) qd); }
void main (void) { OSCQueue q; myObj *item; q = OSCNewQueue(100, Allocator); if (q == 0) { printf("OSCNewQueue() returned 0!\n"); return; } printf("Made an empty queue: "); OSCQueuePrint(q); printf("Inserting three objects.\n"); objects[0].timetag = 5; objects[0].data = "five"; objects[1].timetag = 2; objects[1].data = "two"; objects[2].timetag = 7; objects[2].data = "seven"; if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[0])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[1])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[2])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } printf("Queue with three objects: "); OSCQueuePrint(q); printf("Earliest time tag is %llu.\n", OSCQueueEarliestTimeTag(q)); printf("Remove front item:\n"); item = (myObj *) OSCQueueRemoveEarliest(q); printf("Time tag %llu, data %s\n", item->timetag, item->data); printf("Queue with two objects: "); OSCQueuePrint(q); printf("Inserting three more objects.\n"); objects[3].timetag = 11; objects[3].data = "eleven"; objects[4].timetag = 6; objects[4].data = "six"; objects[5].timetag = 3; objects[5].data = "three"; if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[3])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[4])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } if (OSCQueueInsert(q, (OSCSchedulableObject) &(objects[5])) == FALSE) { printf("OSCQueueInsert() returned FALSE!\n"); return; } printf("Queue with five objects: "); OSCQueuePrint(q); ScanTest(q); StressTest(q); printf("Done!\n"); }