博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RegisterWaitForSingleObject的使用
阅读量:4624 次
发布时间:2019-06-09

本文共 7066 字,大约阅读时间需要 23 分钟。

 

参考:

意图:可控制的线程池

贴一段chrome的封装代码

// Copyright (c) 2012 The Chromium Authors. All rights reserved.// Use of this source code is governed by a BSD-style license that can be// found in the LICENSE file.#include "base/win/object_watcher.h"#include "base/bind.h"#include "base/logging.h"namespace base {namespace win {//-----------------------------------------------------------------------------ObjectWatcher::ObjectWatcher()    : weak_factory_(this),      object_(NULL),      wait_object_(NULL),      origin_loop_(NULL) {}ObjectWatcher::~ObjectWatcher() {  StopWatching();}bool ObjectWatcher::StartWatching(HANDLE object, Delegate* delegate) {  CHECK(delegate);  if (wait_object_) {    NOTREACHED() << "Already watching an object";    return false;  }  // Since our job is to just notice when an object is signaled and report the  // result back to this thread, we can just run on a Windows wait thread.  DWORD wait_flags = WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE;  // DoneWaiting can be synchronously called from RegisterWaitForSingleObject,  // so set up all state now.  callback_ = base::Bind(&ObjectWatcher::Signal, weak_factory_.GetWeakPtr(),                         delegate);  object_ = object;  origin_loop_ = MessageLoop::current();  if (!RegisterWaitForSingleObject(&wait_object_, object, DoneWaiting,                                   this, INFINITE, wait_flags)) {    NOTREACHED() << "RegisterWaitForSingleObject failed: " << GetLastError();    object_ = NULL;    wait_object_ = NULL;    return false;  }  // We need to know if the current message loop is going away so we can  // prevent the wait thread from trying to access a dead message loop.  MessageLoop::current()->AddDestructionObserver(this);  return true;}bool ObjectWatcher::StopWatching() {  if (!wait_object_)    return false;  // Make sure ObjectWatcher is used in a single-threaded fashion.  DCHECK(origin_loop_ == MessageLoop::current());  // Blocking call to cancel the wait. Any callbacks already in progress will  // finish before we return from this call.  if (!UnregisterWaitEx(wait_object_, INVALID_HANDLE_VALUE)) {    NOTREACHED() << "UnregisterWaitEx failed: " << GetLastError();    return false;  }  weak_factory_.InvalidateWeakPtrs();  object_ = NULL;  wait_object_ = NULL;  MessageLoop::current()->RemoveDestructionObserver(this);  return true;}HANDLE ObjectWatcher::GetWatchedObject() {  return object_;}// staticvoid CALLBACK ObjectWatcher::DoneWaiting(void* param, BOOLEAN timed_out) {  DCHECK(!timed_out);  // The destructor blocks on any callbacks that are in flight, so we know that  // that is always a pointer to a valid ObjectWater.  ObjectWatcher* that = static_cast
(param); that->origin_loop_->PostTask(FROM_HERE, that->callback_); that->callback_.Reset();}void ObjectWatcher::Signal(Delegate* delegate) { // Signaling the delegate may result in our destruction or a nested call to // StartWatching(). As a result, we save any state we need and clear previous // watcher state before signaling the delegate. HANDLE object = object_; StopWatching(); delegate->OnObjectSignaled(object);}void ObjectWatcher::WillDestroyCurrentMessageLoop() { // Need to shutdown the watch so that we don't try to access the MessageLoop // after this point. StopWatching();}} // namespace win} // namespace base

测试代码:

// Copyright (c) 2011 The Chromium Authors. All rights reserved.// Use of this source code is governed by a BSD-style license that can be// found in the LICENSE file.#include 
#include "base/message_loop.h"#include "base/win/object_watcher.h"#include "testing/gtest/include/gtest/gtest.h"namespace base {namespace win {namespace {class QuitDelegate : public ObjectWatcher::Delegate { public: virtual void OnObjectSignaled(HANDLE object) { MessageLoop::current()->Quit(); }};class DecrementCountDelegate : public ObjectWatcher::Delegate { public: explicit DecrementCountDelegate(int* counter) : counter_(counter) { } virtual void OnObjectSignaled(HANDLE object) { --(*counter_); } private: int* counter_;};void RunTest_BasicSignal(MessageLoop::Type message_loop_type) { MessageLoop message_loop(message_loop_type); ObjectWatcher watcher; EXPECT_EQ(NULL, watcher.GetWatchedObject()); // A manual-reset event that is not yet signaled. HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); QuitDelegate delegate; bool ok = watcher.StartWatching(event, &delegate); EXPECT_TRUE(ok); EXPECT_EQ(event, watcher.GetWatchedObject()); SetEvent(event); MessageLoop::current()->Run(); EXPECT_EQ(NULL, watcher.GetWatchedObject()); CloseHandle(event);}void RunTest_BasicCancel(MessageLoop::Type message_loop_type) { MessageLoop message_loop(message_loop_type); ObjectWatcher watcher; // A manual-reset event that is not yet signaled. HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); QuitDelegate delegate; bool ok = watcher.StartWatching(event, &delegate); EXPECT_TRUE(ok); watcher.StopWatching(); CloseHandle(event);}void RunTest_CancelAfterSet(MessageLoop::Type message_loop_type) { MessageLoop message_loop(message_loop_type); ObjectWatcher watcher; int counter = 1; DecrementCountDelegate delegate(&counter); // A manual-reset event that is not yet signaled. HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); bool ok = watcher.StartWatching(event, &delegate); EXPECT_TRUE(ok); SetEvent(event); // Let the background thread do its business Sleep(30); watcher.StopWatching(); MessageLoop::current()->RunAllPending(); // Our delegate should not have fired. EXPECT_EQ(1, counter); CloseHandle(event);}void RunTest_OutlivesMessageLoop(MessageLoop::Type message_loop_type) { // Simulate a MessageLoop that dies before an ObjectWatcher. This ordinarily // doesn't happen when people use the Thread class, but it can happen when // people use the Singleton pattern or atexit. HANDLE event = CreateEvent(NULL, TRUE, FALSE, NULL); // not signaled { ObjectWatcher watcher; { MessageLoop message_loop(message_loop_type); QuitDelegate delegate; watcher.StartWatching(event, &delegate); } } CloseHandle(event);}} // namespace//-----------------------------------------------------------------------------TEST(ObjectWatcherTest, BasicSignal) { RunTest_BasicSignal(MessageLoop::TYPE_DEFAULT); RunTest_BasicSignal(MessageLoop::TYPE_IO); RunTest_BasicSignal(MessageLoop::TYPE_UI);}TEST(ObjectWatcherTest, BasicCancel) { RunTest_BasicCancel(MessageLoop::TYPE_DEFAULT); RunTest_BasicCancel(MessageLoop::TYPE_IO); RunTest_BasicCancel(MessageLoop::TYPE_UI);}TEST(ObjectWatcherTest, CancelAfterSet) { RunTest_CancelAfterSet(MessageLoop::TYPE_DEFAULT); RunTest_CancelAfterSet(MessageLoop::TYPE_IO); RunTest_CancelAfterSet(MessageLoop::TYPE_UI);}TEST(ObjectWatcherTest, OutlivesMessageLoop) { RunTest_OutlivesMessageLoop(MessageLoop::TYPE_DEFAULT); RunTest_OutlivesMessageLoop(MessageLoop::TYPE_IO); RunTest_OutlivesMessageLoop(MessageLoop::TYPE_UI);}} // namespace win} // namespace base

转载于:https://www.cnblogs.com/Clingingboy/archive/2013/03/12/2956245.html

你可能感兴趣的文章
MongoDB集群搭建教程收集(待实践)
查看>>
轻量级Web API实现,带接口界面的Jayrock JsonRPC接口组件升级版
查看>>
苹果iOS APP配置HTTPS,iOS ATS配置SSL,苹果ATS标准解决方案
查看>>
Spring中基于AOP的XML架构
查看>>
Spring的JDBC示例
查看>>
JDBC驱动类型
查看>>
Angular内置指令(二)
查看>>
js中浮点型运算 注意点
查看>>
煤气灶---递归
查看>>
STL: unordered_map 自定义键值使用
查看>>
java与<道德经>总章一些感悟
查看>>
数据库查询优化的一些总结
查看>>
ubuntu下hive-0.8.1配置
查看>>
POJ 3169 Layout
查看>>
正则表达式
查看>>
SSL JudgeOnline 1455——电子老鼠闯迷宫
查看>>
类1(this指针/const成员函数/类作用域/外部成员函数/返回this对象的函数)
查看>>
51nod1103(抽屉原理)
查看>>
C++ TCP客户端网络消息发送接收同步实现
查看>>
装饰器
查看>>