summaryrefslogtreecommitdiffstats
path: root/mojo/public/cpp/environment/lib/default_async_waiter.cc
blob: 4dcbe47122528f84652d33814c954e59cb766e25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright 2014 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 "mojo/public/cpp/environment/default_async_waiter.h"

#include <assert.h>

#include "mojo/public/cpp/utility/run_loop.h"
#include "mojo/public/cpp/utility/run_loop_handler.h"

namespace mojo {
namespace {

// RunLoopHandler implementation used for a request to AsyncWait(). There are
// two ways RunLoopHandlerImpl is deleted:
// . when the handle is ready (or errored).
// . when CancelWait() is invoked.
class RunLoopHandlerImpl : public RunLoopHandler {
 public:
  RunLoopHandlerImpl(const Handle& handle,
                     MojoAsyncWaitCallback callback,
                     void* closure)
      : handle_(handle),
        callback_(callback),
        closure_(closure) {
  }

  virtual ~RunLoopHandlerImpl() {
    RunLoop::current()->RemoveHandler(handle_);
  }

  // RunLoopHandler:
  virtual void OnHandleReady(const Handle& handle) MOJO_OVERRIDE {
    NotifyCallback(MOJO_RESULT_OK);
  }

  virtual void OnHandleError(const Handle& handle,
                             MojoResult result) MOJO_OVERRIDE {
    NotifyCallback(result);
  }

 private:
  void NotifyCallback(MojoResult result) {
    // Delete this to unregister the handle. That way if the callback
    // reregisters everything is ok.
    MojoAsyncWaitCallback callback = callback_;
    void* closure = closure_;
    delete this;

    callback(closure, result);
  }

  const Handle handle_;
  MojoAsyncWaitCallback callback_;
  void* closure_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl);
};

MojoAsyncWaitID AsyncWait(MojoHandle handle,
                          MojoWaitFlags flags,
                          MojoDeadline deadline,
                          MojoAsyncWaitCallback callback,
                          void* closure) {
  RunLoop* run_loop = RunLoop::current();
  assert(run_loop);

  // |run_loop_handler| is destroyed either when the handle is ready or if
  // CancelWait is invoked.
  RunLoopHandlerImpl* run_loop_handler =
      new RunLoopHandlerImpl(Handle(handle), callback, closure);
  run_loop->AddHandler(run_loop_handler, Handle(handle), flags, deadline);
  return reinterpret_cast<MojoAsyncWaitID>(run_loop_handler);
}

void CancelWait(MojoAsyncWaitID wait_id) {
  delete reinterpret_cast<RunLoopHandlerImpl*>(wait_id);
}

const MojoAsyncWaiter kDefaultAsyncWaiter = {
  AsyncWait,
  CancelWait
};

}  // namespace

const MojoAsyncWaiter* GetDefaultAsyncWaiter() {
  return &kDefaultAsyncWaiter;
}

}  // namespace mojo