1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/toolkit/crashreporter/google-breakpad/src/client/mac/Framework/OnDemandServer.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,145 @@ 1.4 +// Copyright (c) 2007, Google Inc. 1.5 +// All rights reserved. 1.6 +// 1.7 +// Redistribution and use in source and binary forms, with or without 1.8 +// modification, are permitted provided that the following conditions are 1.9 +// met: 1.10 +// 1.11 +// * Redistributions of source code must retain the above copyright 1.12 +// notice, this list of conditions and the following disclaimer. 1.13 +// * Redistributions in binary form must reproduce the above 1.14 +// copyright notice, this list of conditions and the following disclaimer 1.15 +// in the documentation and/or other materials provided with the 1.16 +// distribution. 1.17 +// * Neither the name of Google Inc. nor the names of its 1.18 +// contributors may be used to endorse or promote products derived from 1.19 +// this software without specific prior written permission. 1.20 +// 1.21 +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.22 +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.23 +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.24 +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.25 +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.26 +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.27 +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.28 +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.29 +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.30 +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.31 +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.32 + 1.33 +#include <mach/mach.h> 1.34 +#include <servers/bootstrap.h> 1.35 +#include <stdio.h> 1.36 +#include <stdlib.h> 1.37 +#include <sys/stat.h> 1.38 +#include <unistd.h> 1.39 + 1.40 +//============================================================================== 1.41 +// class OnDemandServer : 1.42 +// A basic on-demand server launcher supporting a single named service port 1.43 +// 1.44 +// Example Usage : 1.45 +// 1.46 +// kern_return_t result; 1.47 +// OnDemandServer *server = OnDemandServer::Create("/tmp/myserver", 1.48 +// "com.MyCompany.MyServiceName", 1.49 +// true, 1.50 +// &result); 1.51 +// 1.52 +// if (server) { 1.53 +// server->LaunchOnDemand(); 1.54 +// mach_port_t service_port = GetServicePort(); 1.55 +// 1.56 +// // Send a mach message to service_port and "myserver" will be launched 1.57 +// } 1.58 +// 1.59 +// 1.60 +// ---- Now in the server code ---- 1.61 +// 1.62 +// // "myserver" should get the service port and read the message which 1.63 +// // launched it: 1.64 +// mach_port_t service_rcv_port_; 1.65 +// kern_return_t kr = bootstrap_check_in(bootstrap_port, 1.66 +// "com.MyCompany.MyServiceName", 1.67 +// &service_rcv_port_); 1.68 +// // mach_msg() read service_rcv_port_ .... 1.69 +// 1.70 +// .... 1.71 +// 1.72 +// // Later "myserver" may want to unregister the service if it doesn't 1.73 +// // want its bootstrap service to stick around after it exits. 1.74 +// 1.75 +// // DO NOT use mach_port_deallocate() here -- it will fail and the 1.76 +// // following bootstrap_register() will also fail leaving our service 1.77 +// // name hanging around forever (until reboot) 1.78 +// kern_return_t kr = mach_port_destroy(mach_task_self(), service_rcv_port_); 1.79 +// 1.80 +// kr = bootstrap_register(bootstrap_port, 1.81 +// "com.MyCompany.MyServiceName", 1.82 +// MACH_PORT_NULL); 1.83 + 1.84 +class OnDemandServer { 1.85 + public: 1.86 + // must call Initialize() to be useful 1.87 + OnDemandServer() 1.88 + : server_port_(MACH_PORT_NULL), 1.89 + service_port_(MACH_PORT_NULL), 1.90 + unregister_on_cleanup_(true) { 1.91 + } 1.92 + 1.93 + // Creates the bootstrap server and service 1.94 + kern_return_t Initialize(const char *server_command, 1.95 + const char *service_name, 1.96 + bool unregister_on_cleanup); 1.97 + 1.98 + // Returns an OnDemandServer object if successful, or NULL if there's 1.99 + // an error. The error result will be returned in out_result. 1.100 + // 1.101 + // server_command : the full path name including optional command-line 1.102 + // arguments to the executable representing the server 1.103 + // 1.104 + // service_name : represents service name 1.105 + // something like "com.company.ServiceName" 1.106 + // 1.107 + // unregister_on_cleanup : if true, unregisters the service name 1.108 + // when the OnDemandServer is deleted -- unregistering will 1.109 + // ONLY be possible if LaunchOnDemand() has NOT been called. 1.110 + // If false, then the service will continue to be registered 1.111 + // even after the current process quits. 1.112 + // 1.113 + // out_result : if non-NULL, returns the result 1.114 + // this value will be KERN_SUCCESS if Create() returns non-NULL 1.115 + // 1.116 + static OnDemandServer *Create(const char *server_command, 1.117 + const char *service_name, 1.118 + bool unregister_on_cleanup, 1.119 + kern_return_t *out_result); 1.120 + 1.121 + // Cleans up and if LaunchOnDemand() has not yet been called then 1.122 + // the bootstrap service will be unregistered. 1.123 + ~OnDemandServer(); 1.124 + 1.125 + // This must be called if we intend to commit to launching the server 1.126 + // by sending a mach message to our service port. Do not call it otherwise 1.127 + // or it will be difficult (impossible?) to unregister the service name. 1.128 + void LaunchOnDemand(); 1.129 + 1.130 + // This is the port we need to send a mach message to after calling 1.131 + // LaunchOnDemand(). Sending a message causing an immediate launch 1.132 + // of the server 1.133 + mach_port_t GetServicePort() { return service_port_; }; 1.134 + 1.135 + private: 1.136 + // Disallow copy constructor 1.137 + OnDemandServer(const OnDemandServer&); 1.138 + 1.139 + // Cleans up and if LaunchOnDemand() has not yet been called then 1.140 + // the bootstrap service will be unregistered. 1.141 + void Unregister(); 1.142 + 1.143 + name_t service_name_; 1.144 + 1.145 + mach_port_t server_port_; 1.146 + mach_port_t service_port_; 1.147 + bool unregister_on_cleanup_; 1.148 +};