1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 
30 #ifndef MOZC_IPC_PROCESS_WATCH_DOG_H_
31 #define MOZC_IPC_PROCESS_WATCH_DOG_H_
32 
33 #ifndef OS_WIN
34 #include <sys/types.h>
35 #endif  // !OS_WIN
36 
37 #include <memory>
38 
39 #include "base/port.h"
40 #include "base/scoped_handle.h"
41 #include "base/thread.h"
42 
43 // Usage:
44 //
45 // class MyProcessWatchDog {
46 //   void Signaled(SignalType sginal_type) {
47 //      cout << "signaled! " << endl;
48 //   }
49 // }
50 //
51 // MyProcessWatchDog dog;
52 // dog.SetID(pid, tid, -1);
53 
54 namespace mozc {
55 
56 class Mutex;
57 
58 class ProcessWatchDog : public Thread {
59  public:
60   enum SignalType {
61     UNKNOWN_SIGNALED               = 0,  // default value. nerver be signaled.
62     PROCESS_SIGNALED               = 1,  // process is signaled,
63     PROCESS_NOT_FOUND_SIGNALED     = 3,  // process id was not found
64     PROCESS_ACCESS_DENIED_SIGNALED = 4,  // operation was not allowed
65     PROCESS_ERROR_SIGNALED         = 5,  // unkown error in getting process info
66     THREAD_SIGNALED                = 6,  // thread is signaled
67     THREAD_NOT_FOUND_SIGNALED      = 7,  // thread id was not found
68     THREAD_ACCESS_DENIED_SIGNALED  = 8,  // operation was not allowed
69     THREAD_ERROR_SIGNALED          = 9,  // unkown error in getting thread info
70     TIMEOUT_SIGNALED               = 10, // timeout is signaled
71   };
72 
73 #ifdef OS_WIN
74   typedef uint32 ProcessID;
75   typedef uint32 ThreadID;
76 #else
77   typedef pid_t ProcessID;
78   // Linux/Mac has no way to export ThreadID to other process.
79   // For instance, Mac's thread id is just a pointer to the some
80   // internal data structure (_opaque_pthread_t*).
81   typedef uint32 ThreadID;
82 #endif
83 
84   static const ProcessID UnknownProcessID = static_cast<ProcessID>(-1);
85   static const ThreadID UnknownThreadID = static_cast<ThreadID>(-1);
86 
87   // Define a signal handler.
88   // if the given process or thread is terminated, Signaled() is called
89   // with SignalType defined above.
90   // Please note that Signaled() is called from different thread.
Signaled(ProcessWatchDog::SignalType type)91   virtual void Signaled(ProcessWatchDog::SignalType type) {}
92 
93   // Reset process id and thread id.
94   // You can set UnknownProcessID/UnknownProcessID if
95   // they are unknown or not needed to be checked.
96   // This function returns immediately.
97   // You can set the timout for the signal.
98   // If timeout is negative, it waits forever.
99   bool SetID(ProcessID process_id, ThreadID thread_id, int timeout);
100 
101   // internally used by thread
102   void Run();
103 
104   ProcessWatchDog();
105   virtual ~ProcessWatchDog();
106 
107  private:
108 #ifdef OS_WIN
109   ScopedHandle event_;
110 #endif
111   ProcessID process_id_;
112   ThreadID thread_id_;
113   int timeout_;
114   volatile bool is_finished_;
115   std::unique_ptr<Mutex> mutex_;
116 };
117 
118 }  // namespace mozc
119 
120 #endif  // MOZC_IPC_PROCESS_WATCH_DOG_H_
121