00001 /*<std-header orig-src='shore'> 00002 00003 $Id: startstop.cpp,v 1.3 2010/12/09 15:20:16 nhall Exp $ 00004 00005 SHORE -- Scalable Heterogeneous Object REpository 00006 00007 Copyright (c) 1994-99 Computer Sciences Department, University of 00008 Wisconsin -- Madison 00009 All Rights Reserved. 00010 00011 Permission to use, copy, modify and distribute this software and its 00012 documentation is hereby granted, provided that both the copyright 00013 notice and this permission notice appear in all copies of the 00014 software, derivative works or modified versions, and any portions 00015 thereof, and that both notices appear in supporting documentation. 00016 00017 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY 00018 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS 00019 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND 00020 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 00021 00022 This software was developed with support by the Advanced Research 00023 Project Agency, ARPA order number 018 (formerly 8230), monitored by 00024 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518. 00025 Further funding for this work was provided by DARPA through 00026 Rome Research Laboratory Contract No. F30602-97-2-0247. 00027 00028 */ 00029 00030 /* -- do not edit anything above this line -- </std-header>*/ 00031 00032 // This include brings in all header files needed for writing a VAs 00033 // 00034 #include "sm_vas.h" 00035 00036 /* This is about the most minimal storage manager program there is. 00037 * This starts up and shuts down a storage manager, but doesn't 00038 * do any work. 00039 * The purpose of this example is to illustrate the 00040 * program infrastructure needed to use the storage manager. 00041 * 00042 * (Other examples build on this.) 00043 */ 00044 00045 00046 /* smthread-based class for all sm-related work 00047 * 00048 * This class processes run-time options given in argc and argv. 00049 * It also starts up and shuts down a storage manager. 00050 */ 00051 class smthread_user_t : public smthread_t { 00052 int _argc; 00053 char ** _argv; 00054 int _retval; 00055 public: 00056 00057 smthread_user_t(int ac, char **av) 00058 : smthread_t(t_regular, "smthread_user_t"), 00059 _argc(ac), _argv(av), _retval(0) { } 00060 ~smthread_user_t() {} 00061 // run() is virtual in smthread_t. 00062 void run(); // below 00063 int return_value() const { return _retval; } 00064 }; 00065 00066 // for basename: 00067 #include <libgen.h> 00068 void 00069 smthread_user_t::run() 00070 { 00071 /* the storage manager requires that certain options are set. 00072 * Get them from the file named EXAMPLE_SHORECONFIG 00073 */ 00074 option_group_t options(1);// one levels. 00075 /* 00076 * <program name>: <value> 00077 */ 00078 W_COERCE(options.add_class_level(::basename(_argv[0]))); // program name 00079 00080 /* Add the storage manager options to this group. This 00081 * is a static method in ss_m. It adds to the group all 00082 * the options the storage manager uses. All storage 00083 * manager options that have default values are given those defaults. 00084 * You can add your own run-time options to the group as well. 00085 * In this example, we do not have any to add. 00086 */ 00087 W_COERCE(ss_m::setup_options(&options)); 00088 00089 /* Get option values from file EXAMPLE_SHORECONFIG */ 00090 { 00091 /* Scan the file. 00092 * We could scan the command line also or instead: you 00093 * can find an example of this is src/sm/tests/init_config_options.cpp 00094 */ 00095 w_ostrstream err_stream; 00096 const char* opt_file = "EXAMPLE_SHORECONFIG"; // option config file 00097 option_file_scan_t opt_scan(opt_file, &options); 00098 00099 /* Scan the file and override any default option settings. 00100 * Option names must be spelled correctly and in full. 00101 */ 00102 w_rc_t rc = opt_scan.scan(true /*override defaults*/, err_stream, 00103 true /* exact match: option names must match exactly */ 00104 ); 00105 if (rc.is_error()) { 00106 cerr << "Error in reading option file: " << opt_file << endl; 00107 cerr << "\t" << err_stream.c_str() << endl; 00108 _retval = 1; 00109 return; 00110 } 00111 } 00112 00113 /* Check that all required options have been set. 00114 * If an option's attributes indicate that 00115 * a value is required (not optional) and it hasn't 00116 * been given a value (either by default or through the 00117 * file processing above), this will detect the 00118 * missing value. 00119 */ 00120 { 00121 w_ostrstream err_stream; 00122 w_rc_t rc = options.check_required(&err_stream); 00123 if (rc.is_error()) { 00124 cerr << "These required options are not set:" << endl; 00125 cerr << err_stream.c_str() << endl; 00126 _retval = 1; 00127 return; 00128 } 00129 } 00130 00131 00132 /* Now we have done the minimal marshaling of resources to start up 00133 * and shut down a storage manager. 00134 */ 00135 00136 cout << "Starting SSM and performing recovery." << endl; 00137 ss_m* ssm = new ss_m(); 00138 if (!ssm) { 00139 cerr << "Error: Out of memory for ss_m" << endl; 00140 _retval = 1; 00141 return; 00142 } 00143 00144 /* 00145 * Any other work with the storage manager should be 00146 * done here or in child threads forked by this one, 00147 * (passing this ss_m as an argument to those threads) 00148 */ 00149 cout << "Shutting down SSM." << endl; 00150 delete ssm; 00151 ssm = NULL; 00152 } 00153 00154 int 00155 main(int argc, char* argv[]) 00156 { 00157 00158 /* Create an smthread that reads options and starts/stops 00159 * a storage manager 00160 */ 00161 smthread_user_t *smtu = new smthread_user_t(argc, argv); 00162 if (!smtu) 00163 W_FATAL(fcOUTOFMEMORY); 00164 00165 /* cause the thread's run() method to be invoked */ 00166 w_rc_t e = smtu->fork(); 00167 if(e.is_error()) { 00168 cerr << "error forking thread: " << e <<endl; 00169 return 1; 00170 } 00171 00172 /* wait for the thread's run() method to end */ 00173 e = smtu->join(); 00174 if(e.is_error()) { 00175 cerr << "error forking thread: " << e <<endl; 00176 return 1; 00177 } 00178 00179 /* get the thread's result */ 00180 int return_value = smtu->return_value(); 00181 00182 /* clean up */ 00183 delete smtu; 00184 00185 /* return from main() */ 00186 return return_value; 00187 } 00188