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; }
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; }