15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
56d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/cpp/environment/lib/default_async_waiter.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <assert.h>
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
96d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)#include "mojo/public/c/environment/async_waiter.h"
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/utility/run_loop.h"
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/utility/run_loop_handler.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace mojo {
146d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// RunLoopHandler implementation used for a request to AsyncWait(). There are
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// two ways RunLoopHandlerImpl is deleted:
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// . when the handle is ready (or errored).
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// . when CancelWait() is invoked.
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class RunLoopHandlerImpl : public RunLoopHandler {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public:
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoopHandlerImpl(const Handle& handle,
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     MojoAsyncWaitCallback callback,
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                     void* closure)
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      : handle_(handle),
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        callback_(callback),
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        closure_(closure) {
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~RunLoopHandlerImpl() {
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    RunLoop::current()->RemoveHandler(handle_);
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // RunLoopHandler:
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnHandleReady(const Handle& handle) MOJO_OVERRIDE {
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NotifyCallback(MOJO_RESULT_OK);
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void OnHandleError(const Handle& handle,
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                             MojoResult result) MOJO_OVERRIDE {
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    NotifyCallback(result);
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private:
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void NotifyCallback(MojoResult result) {
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Delete this to unregister the handle. That way if the callback
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // reregisters everything is ok.
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MojoAsyncWaitCallback callback = callback_;
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    void* closure = closure_;
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    delete this;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback(closure, result);
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const Handle handle_;
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MojoAsyncWaitCallback callback_;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void* closure_;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MOJO_DISALLOW_COPY_AND_ASSIGN(RunLoopHandlerImpl);
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)MojoAsyncWaitID AsyncWait(MojoHandle handle,
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                          MojoHandleSignals signals,
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          MojoDeadline deadline,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          MojoAsyncWaitCallback callback,
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          void* closure) {
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoop* run_loop = RunLoop::current();
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  assert(run_loop);
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // |run_loop_handler| is destroyed either when the handle is ready or if
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // CancelWait is invoked.
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RunLoopHandlerImpl* run_loop_handler =
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      new RunLoopHandlerImpl(Handle(handle), callback, closure);
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  run_loop->AddHandler(run_loop_handler, Handle(handle), signals, deadline);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return reinterpret_cast<MojoAsyncWaitID>(run_loop_handler);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void CancelWait(MojoAsyncWaitID wait_id) {
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  delete reinterpret_cast<RunLoopHandlerImpl*>(wait_id);
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
836d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}  // namespace
846d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
856d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)namespace internal {
866d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)const MojoAsyncWaiter kDefaultAsyncWaiter = {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AsyncWait,
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  CancelWait
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
926d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles)}  // namespace internal
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace mojo
95