void Inode::NotifyEndClosed(bool writer) { TRACE("Inode %p::%s(%s)\n", this, __FUNCTION__, writer ? "writer" : "reader"); if (writer) { // Our last writer has been closed; if the pipe // contains no data, unlock all waiting readers TRACE(" buffer readable: %zu\n", fBuffer.Readable()); if (fBuffer.Readable() == 0) { ReadRequestList::Iterator iterator = fReadRequests.GetIterator(); while (ReadRequest* request = iterator.Next()) request->Notify(); if (fReadSelectSyncPool) notify_select_event_pool(fReadSelectSyncPool, B_SELECT_READ); } } else { // Last reader is gone. Wake up all writers. fWriteCondition.NotifyAll(); if (fWriteSelectSyncPool) { notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_WRITE); notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_ERROR); } } }
void Inode::NotifyBytesRead(size_t bytes) { // notify writer, if something can be written now size_t writable = fBuffer.Writable(); if (bytes > 0) { // notify select()ors only, if nothing was writable before if (writable == bytes) { if (fWriteSelectSyncPool) notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_WRITE); } // If any of the waiting writers has a minimal write count that has // now become satisfied, we notify all of them (condition variables // don't support doing that selectively). WriteRequest* request; WriteRequestList::Iterator iterator = fWriteRequests.GetIterator(); while ((request = iterator.Next()) != NULL) { size_t minWriteCount = request->MinimalWriteCount(); if (minWriteCount > 0 && minWriteCount <= writable && minWriteCount > writable - bytes) { fWriteCondition.NotifyAll(); break; } } } }
status_t socket_notify(net_socket* _socket, uint8 event, int32 value) { net_socket_private* socket = (net_socket_private*)_socket; bool notify = true; switch (event) { case B_SELECT_READ: if ((ssize_t)socket->receive.low_water_mark > value && value >= B_OK) notify = false; break; case B_SELECT_WRITE: if ((ssize_t)socket->send.low_water_mark > value && value >= B_OK) notify = false; break; case B_SELECT_ERROR: socket->error = value; break; } MutexLocker _(socket->lock); if (notify && socket->select_pool) notify_select_event_pool(socket->select_pool, event); return B_OK; }
void Inode::NotifyBytesWritten(size_t bytes) { // notify reader, if something can be read now if (bytes > 0 && fBuffer.Readable() == bytes) { if (fReadSelectSyncPool) notify_select_event_pool(fReadSelectSyncPool, B_SELECT_READ); if (ReadRequest* request = fReadRequests.First()) request->Notify(); } }
/*! The socket has been connected. It will be moved to the connected queue of its parent socket. */ status_t socket_connected(net_socket* _socket) { net_socket_private* socket = (net_socket_private*)_socket; WeakReference<net_socket_private> parent = socket->parent; if (parent.Get() == NULL) return B_BAD_VALUE; MutexLocker _(parent->lock); parent->pending_children.Remove(socket); parent->connected_children.Add(socket); socket->is_connected = true; // notify parent if (parent->select_pool) notify_select_event_pool(parent->select_pool, B_SELECT_READ); return B_OK; }
void Inode::Open(int openMode) { MutexLocker locker(RequestLock()); if ((openMode & O_ACCMODE) == O_WRONLY) fWriterCount++; if ((openMode & O_ACCMODE) == O_RDONLY || (openMode & O_ACCMODE) == O_RDWR) fReaderCount++; if (fReaderCount > 0 && fWriterCount > 0) { TRACE("Inode %p::Open(): fifo becomes active\n", this); fBuffer.CreateBuffer(); fActive = true; // notify all waiting writers that they can start if (fWriteSelectSyncPool) notify_select_event_pool(fWriteSelectSyncPool, B_SELECT_WRITE); fWriteCondition.NotifyAll(); } }