1 : // Copyright 2013 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Describes a service, which is a persistent background process that uses
16 : // named events and mutexes to communicate and synchronize itself, and presents
17 : // an external API via RPC.
18 :
19 : #ifndef SYZYGY_TRACE_COMMON_SERVICE_H_
20 : #define SYZYGY_TRACE_COMMON_SERVICE_H_
21 :
22 : #include "base/callback.h"
23 : #include "base/strings/string_piece.h"
24 : #include "base/threading/platform_thread.h"
25 :
26 : namespace trace {
27 : namespace common {
28 :
29 : class Service {
30 : public:
31 : typedef base::Callback<bool(Service*)> ServiceCallback;
32 :
33 : enum State {
34 : // This is the starting state for a Service. Once any call to Start, Stop or
35 : // Join has successfully returned it can not return to this state.
36 : kUnused,
37 : kInitialized,
38 : kRunning,
39 : kStopping,
40 : kStopped,
41 : kErrored,
42 : };
43 :
44 : // Constructor.
45 : // @param name The name of this service. Should be a short name, like
46 : // 'call-trace' or 'logger'.
47 : explicit Service(const base::StringPiece16& name);
48 :
49 : // Destructor.
50 : virtual ~Service();
51 :
52 : // @name Mutators. These are not thread-safe.
53 : // @{
54 : void set_instance_id(const base::StringPiece16& instance_id);
55 : void set_started_callback(ServiceCallback callback);
56 : void set_interrupted_callback(ServiceCallback callback);
57 : void set_stopped_callback(ServiceCallback callback);
58 : // @}
59 :
60 : // @name Accessors.
61 : // @{
62 : // These are not thread-safe.
63 E : const std::wstring& name() const { return name_; }
64 E : const std::wstring& instance_id() const { return instance_id_; }
65 E : const ServiceCallback& started_callback() const { return started_callback_; }
66 E : const ServiceCallback& interrupted_callback() const {
67 E : return interrupted_callback_;
68 E : }
69 E : const ServiceCallback& stopped_callback() const { return stopped_callback_; }
70 : // This is thread-safe. As such it requires use of a lock and is not const.
71 : State state();
72 : // @}
73 :
74 : // Launch this service. This method may only be called by the thread that
75 : // created the service. This call is non-blocking and not thread-safe.
76 : // @returns true on success, false otherwise. Logs verbosely.
77 : bool Start();
78 :
79 : // Stops this service. This method may be called by any thread once the
80 : // service has started. This call is non-blocking and thread-safe.
81 : // @returns true on success, false otherwise. Logs verbosely.
82 : bool Stop();
83 :
84 : // Joins the thread on which the service is running, and returns when the
85 : // service has terminated (cleanly, or otherwise). This is a blocking call and
86 : // is thread-safe.
87 : // @returns true on success, false otherwise. Logs verbosely.
88 : bool Join();
89 :
90 : protected:
91 : // Progress callbacks to be used by non-blocking implementations. These
92 : // invoke any external callbacks and transition the state of the service.
93 : // These are thread-safe.
94 : bool OnInitialized();
95 : bool OnStarted();
96 : bool OnInterrupted();
97 : bool OnStopped();
98 :
99 : // @name Functions for derived class to implement.
100 : // @{
101 : // This must be non-blocking. This will only be called by the thread that
102 : // created this service instance. This should indicate progress via the
103 : // 'initialized' and 'started' callbacks.
104 : virtual bool StartImpl() = 0;
105 : // This must be non-blocking. This should indicate progress via the
106 : // 'stopped' callback.
107 : virtual bool StopImpl() = 0;
108 : // This should be blocking and should only return when the service has
109 : // terminated. This will only be called by the thread that created this
110 : // service.
111 : virtual bool JoinImpl() = 0;
112 : // @}
113 :
114 : // Testing seam for state transitions.
115 E : virtual void OnStateChange(State old_state, State new_state) { }
116 :
117 : private:
118 : // Sets the current state. This grabs lock_, so must not be called while it is
119 : // already held.
120 : // @param state The new state to be set.
121 : void set_state(State state);
122 :
123 : std::wstring name_;
124 : std::wstring instance_id_;
125 :
126 : // Service callbacks.
127 : ServiceCallback started_callback_;
128 : ServiceCallback interrupted_callback_;
129 : ServiceCallback stopped_callback_;
130 :
131 : // The ID of the thread that created this logger. Because of the intricacies
132 : // of RPC some operations may only be performed by the owning thread and we
133 : // enforce that using this. This is only used for DCHECKs.
134 : base::PlatformThreadId owning_thread_id_;
135 :
136 : // The current state of the service instance.
137 : State state_;
138 :
139 : DISALLOW_COPY_AND_ASSIGN(Service);
140 : };
141 :
142 : } // namespace common
143 : } // namespace trace
144 :
145 : #endif // SYZYGY_TRACE_COMMON_SERVICE_H_
|