1 : /* -*- c++ -*- */
2 : /*
3 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_REVERSE_SERVICE_REVERSE_SERVICE_H_
9 : #define NATIVE_CLIENT_SRC_TRUSTED_REVERSE_SERVICE_REVERSE_SERVICE_H_
10 :
11 : #include <set>
12 :
13 : #include "native_client/src/include/nacl_compiler_annotations.h"
14 : #include "native_client/src/include/nacl_macros.h"
15 : #include "native_client/src/include/nacl_scoped_ptr.h"
16 : #include "native_client/src/include/nacl_string.h"
17 : #include "native_client/src/trusted/reverse_service/manifest_rpc.h"
18 : #include "native_client/src/trusted/reverse_service/reverse_control_rpc.h"
19 : #include "native_client/src/trusted/reverse_service/reverse_socket.h"
20 : #include "native_client/src/trusted/service_runtime/include/sys/nacl_name_service.h"
21 : #include "native_client/src/shared/platform/refcount_base.h"
22 : #include "native_client/src/shared/platform/nacl_sync.h"
23 :
24 : namespace nacl {
25 :
26 : class DescWrapper;
27 :
28 2 : class ReverseInterface : public RefCountBase {
29 : public:
30 0 : virtual ~ReverseInterface() {}
31 :
32 : // For debugging, messaging. |message| goes to JavaScript console.
33 : virtual void Log(nacl::string message) = 0;
34 :
35 : // Startup handshake
36 : virtual void StartupInitializationComplete() = 0;
37 :
38 : // Name service use.
39 : //
40 : // Some of these functions require that the actual operation be done
41 : // in a different thread, so that the implementation of the
42 : // interface will have to block the requesting thread. However, on
43 : // surf away, the thread switch may get cancelled, and the
44 : // implementation will have to reply with a failure indication.
45 :
46 : // The bool functions returns false if the service thread unblocked
47 : // because of surf-away, shutdown, or other issues. The plugin,
48 : // when it tells sel_ldr to shut down, will also signal all threads
49 : // that are waiting for main thread callbacks to wake up and abandon
50 : // their vigil after the callbacks are all cancelled (by abandoning
51 : // the WeakRefAnchor or by bombing their CompletionCallbackFactory).
52 : // Since shutdown/surfaway is the only admissible error, we use bool
53 : // as the return type.
54 : virtual bool EnumerateManifestKeys(std::set<nacl::string>* keys) = 0;
55 : virtual bool OpenManifestEntry(nacl::string url_key, int32_t* out_desc) = 0;
56 : virtual bool CloseManifestEntry(int32_t desc) = 0;
57 : virtual void ReportCrash() = 0;
58 :
59 : // The low-order 8 bits of the |exit_status| should be reported to
60 : // any interested parties.
61 : virtual void ReportExitStatus(int exit_status) = 0;
62 :
63 : // Standard output and standard error redirection, via setting
64 : // NACL_EXE_STDOUT to the string "DEBUG_ONLY:dev://postmessage" (see
65 : // native_client/src/trusted/nacl_resource.* and sel_ldr). NB: the
66 : // contents of |message| is arbitrary bytes and not an Unicode
67 : // string, so the implementation should take care to handle this
68 : // appropriately.
69 : virtual void DoPostMessage(nacl::string message) = 0;
70 :
71 : // Quota checking for files that were sent to the untrusted module.
72 : // TODO(sehr): remove the stub interface once the plugin provides one.
73 : virtual int64_t RequestQuotaForWrite(nacl::string file_id,
74 : int64_t offset,
75 0 : int64_t bytes_to_write) {
76 : UNREFERENCED_PARAMETER(file_id);
77 : UNREFERENCED_PARAMETER(offset);
78 0 : return bytes_to_write;
79 : }
80 :
81 : // covariant impl of Ref()
82 0 : ReverseInterface* Ref() { // down_cast
83 0 : return reinterpret_cast<ReverseInterface*>(RefCountBase::Ref());
84 : }
85 : };
86 :
87 : class ReverseService : public RefCountBase {
88 : public:
89 : ReverseService(nacl::DescWrapper* conn_cap, ReverseInterface* rif);
90 :
91 : // covariant impl of Ref()
92 5 : ReverseService* Ref() { // down_cast
93 5 : return reinterpret_cast<ReverseService*>(RefCountBase::Ref());
94 : }
95 :
96 : // Start starts the reverse service by initiating a connection on
97 : // the conn_cap and spawning a service thread using the
98 : // ReverseInterface rif, both provided in the ctor.
99 : //
100 : // If |crash_report| is true, then the ReportCrash virtual function
101 : // will be invoked when the reverse channel is closed. Typically
102 : // this is needed only in one (the "primary" or "bootstrap")
103 : // instance of the reverse service, since additional channels
104 : // created are often used for and are under application program
105 : // control, and the untrusted application should be able to close
106 : // those channels without generating a false crash report.
107 : bool Start(bool crash_report);
108 :
109 2 : bool Start() {
110 2 : return Start(true);
111 : }
112 :
113 : void WaitForServiceThreadsToExit();
114 :
115 : void IncrThreadCount();
116 : void DecrThreadCount();
117 :
118 14 : ReverseInterface* reverse_interface() const { return reverse_interface_; }
119 :
120 : protected:
121 : ~ReverseService();
122 :
123 : private:
124 : NACL_DISALLOW_COPY_AND_ASSIGN(ReverseService);
125 :
126 : // We cannot just have the object here, since MSVC generates warning
127 : // C4355 that 'this' is used in base member initializer list. Meh.
128 : // It's a fair warning: 'this' isn't fully constructed yet.
129 : scoped_ptr<ReverseSocket> service_socket_;
130 : ReverseInterface* reverse_interface_;
131 :
132 : static NaClSrpcHandlerDesc const handlers[];
133 :
134 : NaClMutex mu_;
135 : NaClCondVar cv_;
136 : uint32_t thread_count_;
137 : };
138 :
139 : } // namespace nacl
140 :
141 : #endif
|