status_t Inode::Select(uint8 event, selectsync* sync, int openMode) { bool writer = true; select_sync_pool** pool; if ((openMode & O_RWMASK) == O_RDONLY) { pool = &fReadSelectSyncPool; writer = false; } else if ((openMode & O_RWMASK) == O_WRONLY) { pool = &fWriteSelectSyncPool; } else return B_NOT_ALLOWED; if (add_select_sync_pool_entry(pool, sync, event) != B_OK) return B_ERROR; // signal right away, if the condition holds already if (writer) { if ((event == B_SELECT_WRITE && (fBuffer.Writable() > 0 || fReaderCount == 0)) || (event == B_SELECT_ERROR && fReaderCount == 0)) { return notify_select_event(sync, event); } } else { if (event == B_SELECT_READ && (fBuffer.Readable() > 0 || fWriterCount == 0)) { return notify_select_event(sync, event); } } return B_OK; }
// _HandleRequest status_t KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request) { // check and execute the request status_t result = B_OK; if (fFileSystem->KnowsSelectSyncEntry(request->sync)) { if (request->unspecifiedEvent) { // old style add-ons can't provide an event argument; we shoot // all events notify_select_event(request->sync, B_SELECT_READ); notify_select_event(request->sync, B_SELECT_WRITE); notify_select_event(request->sync, B_SELECT_ERROR); } else { PRINT(("notify_select_event(%p, %d)\n", request->sync, (int)request->event)); notify_select_event(request->sync, request->event); } } else result = B_BAD_VALUE; // prepare the reply RequestAllocator allocator(fPort->GetPort()); NotifySelectEventReply* reply; status_t error = AllocateRequest(allocator, &reply); if (error != B_OK) return error; reply->error = result; // send the reply return fPort->SendRequest(&allocator); }
void VBoxGuestNativeISRMousePollEvent(PVBOXGUESTDEVEXT pDevExt) { LogFlow((MODULE_NAME "::NativeISRMousePollEvent:\n")); status_t err = B_OK; //dprintf(MODULE_NAME ": isr mouse\n"); /* * Wake up poll waiters. */ //selwakeup(&g_SelInfo); //XXX:notify_select_event(); RTSpinlockAcquire(g_Spinlock); if (sState.selectSync) { //dprintf(MODULE_NAME ": isr mouse: notify\n"); notify_select_event(sState.selectSync, sState.selectEvent); sState.selectEvent = (uint8_t)0; sState.selectRef = (uint32_t)0; sState.selectSync = NULL; } else err = B_ERROR; RTSpinlockRelease(g_Spinlock); }
/** * Driver select hook. * * @param cookie The session. * @param event The event. * @param ref ??? * @param sync ??? * * @return Haiku status code. */ static status_t vgdrvHaikuSelect(void *cookie, uint8 event, uint32 ref, selectsync *sync) { PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie; status_t err = B_OK; switch (event) { case B_SELECT_READ: break; default: return EINVAL; } RTSpinlockAcquire(g_DevExt.SessionSpinlock); uint32_t u32CurSeq = ASMAtomicUoReadU32(&g_DevExt.u32MousePosChangedSeq); if (pSession->u32MousePosChangedSeq != u32CurSeq) { pSession->u32MousePosChangedSeq = u32CurSeq; notify_select_event(sync, event); } else if (sState.selectSync == NULL) { sState.selectEvent = (uint8_t)event; sState.selectRef = (uint32_t)ref; sState.selectSync = (void *)sync; } else err = B_WOULD_BLOCK; RTSpinlockRelease(g_DevExt.SessionSpinlock); return err; }
status_t socket_request_notification(net_socket* _socket, uint8 event, selectsync* sync) { net_socket_private* socket = (net_socket_private*)_socket; mutex_lock(&socket->lock); status_t status = add_select_sync_pool_entry(&socket->select_pool, sync, event); mutex_unlock(&socket->lock); if (status != B_OK) return status; // check if the event is already present // TODO: add support for poll() types switch (event) { case B_SELECT_READ: { ssize_t available = socket_read_avail(socket); if ((ssize_t)socket->receive.low_water_mark <= available || available < B_OK) notify_select_event(sync, event); break; } case B_SELECT_WRITE: { ssize_t available = socket_send_avail(socket); if ((ssize_t)socket->send.low_water_mark <= available || available < B_OK) notify_select_event(sync, event); break; } case B_SELECT_ERROR: // TODO: B_SELECT_ERROR condition! break; } return B_OK; }
/** * Driver close hook. * @param cookie The session. * * @return Haiku status code. */ static status_t vgdrvHaikuClose(void *cookie) { PVBOXGUESTSESSION pSession = (PVBOXGUESTSESSION)cookie; Log(("vgdrvHaikuClose: pSession=%p\n", pSession)); /** @todo r=ramshankar: should we really be using the session spinlock here? */ RTSpinlockAcquire(g_DevExt.SessionSpinlock); /** @todo we don't know if it belongs to this session!! */ if (sState.selectSync) { //dprintf(DRIVER_NAME "close: unblocking select %p %x\n", sState.selectSync, sState.selectEvent); notify_select_event(sState.selectSync, sState.selectEvent); sState.selectEvent = (uint8_t)0; sState.selectRef = (uint32_t)0; sState.selectSync = (void *)NULL; } RTSpinlockRelease(g_DevExt.SessionSpinlock); return B_OK; }