/* browserReceiveData: Called in response to a CMD_RECEIVE_DATA message. Retrieves the data file name and signals the semaphore. */ static void browserReceiveData() { char *localName= NULL; int id, ok; browserReceive(&id, 4); browserReceive(&ok, 4); DPRINT("VM: receiving data id: %i state %i\n", id, ok); if (ok == 1) { int length= 0; browserReceive(&length, 4); if (length) { localName= malloc(length+1); browserReceive(localName, length); localName[length]= 0; DPRINT("VM: got filename %s\n", localName); } } if (id >= 0 && id < MAX_REQUESTS) { sqStreamRequest *req= requests[id]; if (req) { req->localName= localName; req->state= ok; DPRINT("VM: signaling semaphore, state=%i\n", ok); /* synchronizedSignalSemaphoreWithIndex(req->semaIndex);*/ signalSemaphoreWithIndex(req->semaIndex); } } }
static void signalInputEvent(void) { #if DEBUG_EVENTS printf("signalInputEvent\n"); #endif if (inputEventSemaIndex > 0) signalSemaphoreWithIndex(inputEventSemaIndex); }
/* UnixAioPlugin>>#aioForward:withData:andFlags: */ static void aioForwardwithDataandFlags(int fd, void *data, int flags) { int *pfd; sqInt semaIndex; pfd = data; semaIndex = *pfd; signalSemaphoreWithIndex(semaIndex); }
void eventThread(void* data) { int evt_semaphore = (int)data; while (1) { int count = getPendingEvents(); while (count--) { signalSemaphoreWithIndex(evt_semaphore); } yield(); } }
/* The Solaris STREAMS audio driver sends a SIGIO * each time it reads the EOF sent by sound_PlaySamplesFromAtLength */ static void auHandle(int sig) { PRINTF(("(sig=%d)", sig)); if (auFd < 0) return; /* Not all SIGIOs are for us */ if (sound_AvailableSpace() > 0) { PRINTF(("Signalling semaphore %d", auPlaySemaIndex)); signalSemaphoreWithIndex(auPlaySemaIndex); } }
int Java_org_squeak_android_SqueakVM_sendEvent(JNIEnv *env, jobject self, int type, int stamp, int arg3, int arg4, int arg5, int arg6, int arg7, int arg8) { sqInputEvent *event = sqNextEventPut(); event->type = type; event->timeStamp = stamp; event->unused1 = arg3; event->unused2 = arg4; event->unused3 = arg5; event->unused4 = arg6; event->unused5 = arg7; event->windowIndex = arg8; if(inputSemaphoreIndex) signalSemaphoreWithIndex(inputSemaphoreIndex); }
/* Signal the external semaphore with the given index. Answer non-zero on * success, zero otherwise. This function is (should be) thread-safe; * multiple threads may attempt to signal the same semaphore without error. * An index of zero should be and is silently ignored. * * (sig) As well as negative index. */ sqInt signalSemaphoreWithIndex(sqInt index) { int next; /* An index of zero should be and is silently ignored. */ if (index <=0) return 0; /* we must use the locking semantics to avoid ABA problem on writing a semaphore index to queue, so there is no chance for fetching thread to observe queue in inconsistent state. */ lockSignalQueue(); /* check for queue overflow */ next = succIndex(sigIndexHigh); if (next == sigIndexLow ) { #if SQ_DYNAMIC_QUEUE_SIZE // grow and retry unlockSignalQueue(); ioGrowSignalQueue( maxPendingSignals + 100); return signalSemaphoreWithIndex(index); #else unlockSignalQueue(); // error if queue size is static (perhaps better would be to sleep for a while and retry?) error("External semaphore signal queue overflow"); #endif } signalQueue[sigIndexHigh] = index; /* make sure semaphore index is written before we advance sigIndexHigh */ sqLowLevelMFence(); sigIndexHigh = next; /* reset lock */ unlockSignalQueue(); forceInterruptCheck(); return 1; }
// tell the SoundPlayer that output can be written. // static void ioProcSignal(int semaphore) { if (semaphore) signalSemaphoreWithIndex(semaphore); }
/* Process audio events from the NAS server. The same routine is used whether we are recording or playing back */ static void handleAudioEvents(int fd, void *data, int flags) { if(!server) { DPRINTF( "handleAudioEvents called while unconnected!\n"); return; } /* read events once */ AuEventsQueued(server, AuEventsQueuedAfterReading); /* then loop through the read queue */ while(AuEventsQueued(server, AuEventsQueuedAlready)) { AuEvent event; AuNextEvent(server, AuTrue, &event); DPRINTF("event of type %d\n", event.type); switch(event.type) { case 0: { AuErrorEvent *errEvent = (AuErrorEvent *) &event; char errdesc[1000]; AuGetErrorText(server, errEvent->error_code, errdesc, sizeof(errdesc)); fprintf(stderr, "audio error: %s\n", errdesc); sound_Stop(); return; /* return, not break, so that we don't process the now-closed server any longer! */ } case AuEventTypeElementNotify: { AuElementNotifyEvent *enEvent = (AuElementNotifyEvent *)&event; switch(enEvent->kind) { case AuElementNotifyKindLowWater: DPRINTF("low water event\n"); bytesAvail += enEvent->num_bytes; break; case AuElementNotifyKindHighWater: DPRINTF("high water event\n"); bytesAvail += enEvent->num_bytes; break; case AuElementNotifyKindState: DPRINTF("state change (%d->%d)\n", enEvent->prev_state, enEvent->cur_state); bytesAvail += enEvent->num_bytes; if(enEvent->cur_state == AuStatePause) { /* if the flow has stopped, then arrange for it to get started again */ /* XXX there is probably a more intelligent place to do this, in case there is a real reason it has paused */ DPRINTF("unpausing\n"); AuStartFlow(server, flow, NULL); AuFlush(server); } break; } } } } if(bytesAvail > 0) { DPRINTF("bytesAvail: %d\n", bytesAvail); signalSemaphoreWithIndex(semaIndex); } aioHandle(fd, handleAudioEvents, flags & AIO_RW); }