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

本文共 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

你可能感兴趣的文章
Java设计模式-Builder生成器模式
查看>>
Delphi中ListView和TreeView的Item中的内存泄露
查看>>
Python内置函数(55)——globals
查看>>
BZOJ4472
查看>>
mysql四-2:多表查询
查看>>
OpenStack之Nova模块
查看>>
C#矩阵求逆
查看>>
LK光流法
查看>>
【面试】求数组子序列的最大和
查看>>
CentOS设置默认启动命令行(不启动图形界面)
查看>>
设计模式-1-单例模式
查看>>
java 读写锁
查看>>
_itoa_s替换 itoa
查看>>
面试问题
查看>>
Jmeter-【JSON Extractor】-响应结果中一级key取值
查看>>
mysql建库
查看>>
bzoj1066: [SCOI2007]蜥蜴
查看>>
jQuery自定义右键菜单
查看>>
mybatis实现延迟加载多对一
查看>>
JS拖拽,移动与拉伸
查看>>