标签:cat wait oop tps likely 用法 ack done pretty
上一篇分析MessagePumpForUI,参考chromium之message_pump_win之二
MessagePumpForIO,同MessagePumpForUI,也是要实现三个函数
// MessagePump methods: virtual void ScheduleWork(); virtual void ScheduleDelayedWork(const Time& delayed_work_time); virtual void DoRunLoop();
先看看典型用法
第一种用法是不需要读取数据到buffer,因此所有的清理工作可以交给message pump
第二种用法是需要读取buffer,需要手动delete IOContext
第三种用法是在第二种的基础上,析构函数等待所有的IO结束
// Clients interested in receiving OS notifications when asynchronous IO // operations complete should implement this interface and register themselves // with the message pump. // // Typical use #1: // // Use only when there are no user‘s buffers involved on the actual IO, // // so that all the cleanup can be done by the message pump. // class MyFile : public IOHandler { // MyFile() { // ... // context_ = new IOContext; // context_->handler = this; // message_pump->RegisterIOHandler(file_, this); // } // ~MyFile() { // if (pending_) { // // By setting the handler to NULL, we‘re asking for this context // // to be deleted when received, without calling back to us. // context_->handler = NULL; // } else { // delete context_; // } // } // virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered, // DWORD error) { // pending_ = false; // } // void DoSomeIo() { // ... // // The only buffer required for this operation is the overlapped // // structure. // ConnectNamedPipe(file_, &context_->overlapped); // pending_ = true; // } // bool pending_; // IOContext* context_; // HANDLE file_; // }; // // Typical use #2: // class MyFile : public IOHandler { // MyFile() { // ... // message_pump->RegisterIOHandler(file_, this); // } // // Plus some code to make sure that this destructor is not called // // while there are pending IO operations. // ~MyFile() { // } // virtual void OnIOCompleted(IOContext* context, DWORD bytes_transfered, // DWORD error) { // ... // delete context; // } // void DoSomeIo() { // ... // IOContext* context = new IOContext; // // This is not used for anything. It just prevents the context from // // being considered "abandoned". // context->handler = this; // ReadFile(file_, buffer, num_bytes, &read, &context->overlapped); // } // HANDLE file_; // }; // // Typical use #3: // Same as the previous example, except that in order to deal with the // requirement stated for the destructor, the class calls WaitForIOCompletion // from the destructor to block until all IO finishes. // ~MyFile() { // while(pending_) // message_pump->WaitForIOCompletion(INFINITE, this); // } //
来来来,上代码
1)have_work_ = 1;
2)通知MessagePump 工作
void MessagePumpForIO::ScheduleWork() { if (InterlockedExchange(&have_work_, 1)) return; // Someone else continued the pumping. // Make sure the MessagePump does some work for us. BOOL ret = PostQueuedCompletionStatus(port_, 0, reinterpret_cast<ULONG_PTR>(this), reinterpret_cast<OVERLAPPED*>(this)); DCHECK(ret); } void MessagePumpForIO::ScheduleDelayedWork(const Time& delayed_work_time) { // We know that we can‘t be blocked right now since this method can only be // called on the same thread as Run, so we only need to update our record of // how long to sleep when we do sleep. delayed_work_time_ = delayed_work_time; }
最后一个
void MessagePumpForIO::DoRunLoop() { for (;;) { // If we do any work, we may create more messages etc., and more work may // possibly be waiting in another task group. When we (for example) // WaitForIOCompletion(), there is a good chance there are still more // messages waiting. On the other hand, when any of these methods return // having done no work, then it is pretty unlikely that calling them // again quickly will find any work to do. Finally, if they all say they // had no work, then it is a good time to consider sleeping (waiting) for // more work. bool more_work_is_plausible = state_->delegate->DoWork(); if (state_->should_quit) break; more_work_is_plausible |= WaitForIOCompletion(0, NULL); if (state_->should_quit) break; more_work_is_plausible |= state_->delegate->DoDelayedWork(&delayed_work_time_); if (state_->should_quit) break; if (more_work_is_plausible) continue; more_work_is_plausible = state_->delegate->DoIdleWork(); if (state_->should_quit) break; if (more_work_is_plausible) continue; WaitForWork(); // Wait (sleep) until we have work to do again. } }
标签:cat wait oop tps likely 用法 ack done pretty
原文地址:https://www.cnblogs.com/ckelsel/p/9218835.html