blob: 53bf76dc43568c01322992aefbecc6c57ebcc5c4 [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef MOZC_IPC_NAMED_EVENT_H_
#define MOZC_IPC_NAMED_EVENT_H_
#ifdef OS_WIN
#include <windows.h>
#else
#include <semaphore.h>
#endif
#include <string>
#include "base/port.h"
// Named Event class for Inter Process Communication:
// This is a shallow wrapper for Windows CreateEvent() API.
// For Linux/Mac, emulate the CreateEvent behavior
// with SysV Semaphore
//
// Example:
//
// (Process 1)
// NamedEventListener listner("foo"); // Create named event listener named foo
// CHECK(listener.IsAvailable());
// listener.Wait(10000); // Wait until an event comes.
// Access shared resource
//
// (Process 2)
// NamedEventNotifier notifier("foo"); // Open named event
// CHECK(notifier.IsAvailable())
// send signals to the listener blocked with Wait() method
// notifier.Notify();
//
// After mozc UI launches mozc_server.exe,
// mozc UI needs to wait until mozc_server is ready.
// For this purpose, mozc UI makes a listener object.
// When mozc_server completes all initialization and
// is ready for conversion, mozc_server sends a notification
// event to the client.
//
// Example
// - UI process
// if (mozc_server is not running) {
// CreateProcess("mozc_server.exe" ...);
// mozc::NamedEventListener l("session");
// Display Splash Window
// l.Wait(10000); // 10 second
// Close splash window
// Start conversion
// }
//
// - Server process
// Initialize all static objects
// Start session server
// mozc::NamedEventNotifier n("session");
// n.Notify();
namespace mozc {
// Util class for Named Event
class NamedEventUtil {
public:
// return real event name
// Windows: <kEventPathPrefix>.<sid>.<name>
// Linux/Mac: <Util::GetUserProfileDirectory()>/.<name>.event
static const string GetEventPath(const char *name);
private:
DISALLOW_COPY_AND_ASSIGN(NamedEventUtil);
};
class NamedEventListener {
public:
// Create Named Event named "name"
// Windows: <kEventPathPrefix>.<sid>.<name>
// Linux/Mac: <Util::GetUserProfileDirectory()>/.event.<name>
explicit NamedEventListener(const char *name);
virtual ~NamedEventListener();
// Return true if NamedEventListener is available
bool IsAvailable() const;
// return true if NamedEventListner is created by this instance.
// If NamedEventListner opened an exiting handle, return false.
bool IsOwner() const;
// Wait until the listener receives a notification
// event from NamedEventNotifier.
// You can set the timeout (in msec)
// if timeout is negative, Waits forever.
bool Wait(int msec);
// Wait until the listener receives a notification or
// the process specfied with pid is terminated.
// return TIMEOUT: reached timeout
// return EVENT_SIGNALED: event is signaled.
// return PROCESS_SIGNALED: process is signaled.
// NOTE: Only available on Windows and Linux.
enum {
TIMEOUT = 0,
EVENT_SIGNALED = 1,
PROCESS_SIGNALED = 2,
};
int WaitEventOrProcess(int msec, size_t pid);
private:
bool is_owner_;
#ifdef OS_WIN
HANDLE handle_;
#else
sem_t *sem_;
string key_filename_;
#endif
};
class NamedEventNotifier {
public:
// Open Named event named "name"
// The named event object should be created by
// NamedEventListener before calling the constructor
explicit NamedEventNotifier(const char *name);
virtual ~NamedEventNotifier();
// return true if NamedEventNotifier is available
bool IsAvailable() const;
// send an wake-up signal to NamedEventListener
bool Notify();
private:
#ifdef OS_WIN
HANDLE handle_;
#else
sem_t *sem_;
#endif
};
} // namespace mozc
#endif // MOZC_IPC_NAMED_EVENT_H_