void UnixSocketImpl::OnFileCanWriteWithoutBlocking(int aFd) { MOZ_ASSERT(!NS_IsMainThread()); MOZ_ASSERT(!mShuttingDownOnIOThread); // Try to write the bytes of mCurrentRilRawData. If all were written, continue. // // Otherwise, save the byte position of the next byte to write // within mCurrentRilRawData, and request another write when the // system won't block. // MOZ_ASSERT(aFd >= 0); while (true) { UnixSocketRawData* data; if (mOutgoingQ.IsEmpty()) { return; } data = mOutgoingQ.ElementAt(0); const uint8_t *toWrite; toWrite = data->mData; while (data->mCurrentWriteOffset < data->mSize) { ssize_t write_amount = data->mSize - data->mCurrentWriteOffset; ssize_t written; written = write (aFd, toWrite + data->mCurrentWriteOffset, write_amount); if (written > 0) { data->mCurrentWriteOffset += written; } if (written != write_amount) { break; } } if (data->mCurrentWriteOffset != data->mSize) { MessageLoopForIO::current()->WatchFileDescriptor( aFd, false, MessageLoopForIO::WATCH_WRITE, &mWriteWatcher, this); return; } mOutgoingQ.RemoveElementAt(0); delete data; } }
void UnixSocketImpl::OnFileCanWriteWithoutBlocking(int aFd) { MOZ_ASSERT(!NS_IsMainThread()); MOZ_ASSERT(!mShuttingDownOnIOThread); SocketConnectionStatus status = mConsumer->GetConnectionStatus(); if (status == SOCKET_CONNECTED) { // Try to write the bytes of mCurrentRilRawData. If all were written, continue. // // Otherwise, save the byte position of the next byte to write // within mCurrentRilRawData, and request another write when the // system won't block. // while (true) { UnixSocketRawData* data; if (mOutgoingQ.IsEmpty()) { return; } data = mOutgoingQ.ElementAt(0); const uint8_t *toWrite; toWrite = data->mData; while (data->mCurrentWriteOffset < data->mSize) { ssize_t write_amount = data->mSize - data->mCurrentWriteOffset; ssize_t written; written = write (aFd, toWrite + data->mCurrentWriteOffset, write_amount); if (written > 0) { data->mCurrentWriteOffset += written; } if (written != write_amount) { break; } } if (data->mCurrentWriteOffset != data->mSize) { MessageLoopForIO::current()->WatchFileDescriptor( aFd, false, MessageLoopForIO::WATCH_WRITE, &mWriteWatcher, this); return; } mOutgoingQ.RemoveElementAt(0); delete data; } } else if (status == SOCKET_CONNECTING) { int error, ret; socklen_t len = sizeof(error); ret = getsockopt(mFd.get(), SOL_SOCKET, SO_ERROR, &error, &len); if (ret || error) { NS_WARNING("getsockopt failure on async socket connect!"); nsRefPtr<OnSocketEventTask> t = new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); NS_DispatchToMainThread(t); return; } if (!mConnector->SetUp(mFd)) { NS_WARNING("Could not set up socket!"); nsRefPtr<OnSocketEventTask> t = new OnSocketEventTask(this, OnSocketEventTask::CONNECT_ERROR); NS_DispatchToMainThread(t); return; } nsRefPtr<OnSocketEventTask> t = new OnSocketEventTask(this, OnSocketEventTask::CONNECT_SUCCESS); NS_DispatchToMainThread(t); SetUpIO(); } }