00001 // Defines a main function for running CL2 standalone, without being 00002 // attached to any application. 00003 00004 #include "application_config.h" 00005 #include "ac_app_context_private.h" 00006 #include "kr_controller.h" 00007 #include "client-run.h" 00008 #include "epoc-ao-gerror.hpp" 00009 #include "er_errors.h" 00010 00011 #include "common/utilities.h" 00012 00013 #include <e32base.h> // CTrapCleanup 00014 00015 #include <stdlib.h> // abort 00016 00017 static CActiveSchedulerWait* globalLoop = NULL; 00018 00019 // Immediate process exit. 00020 extern "C" void ExitApplication() 00021 { 00022 logt("ExitApplication"); 00023 // This should make sure that the process gets killed, assuming it 00024 // is the main process that calls this. 00025 User::Exit(KErrGeneral); 00026 } 00027 00028 // Orderly shutdown. 00029 extern "C" void ShutdownApplication() 00030 { 00031 logt("ShutdownApplication"); 00032 if (globalLoop) { 00033 globalLoop->AsyncStop(); 00034 } else { 00035 logt("error, no scheduler"); 00036 ExitApplication(); 00037 } 00038 } 00039 00040 NONSHARABLE_CLASS(CMainObj) : 00041 public CBase, 00042 public MAppContextInitObserver 00043 { 00044 public: 00045 static CMainObj* NewL(); 00046 ~CMainObj(); 00047 private: 00048 void ConstructL(); 00049 private: // MAppContextInitObserver 00050 void AppContextReady(TInt aError); 00051 private: 00052 kr_Controller* client; 00053 }; 00054 00055 CMainObj* CMainObj::NewL() 00056 { 00057 CMainObj* obj = new (ELeave) CMainObj; 00058 CleanupStack::PushL(obj); 00059 obj->ConstructL(); 00060 CleanupStack::Pop(obj); 00061 return obj; 00062 } 00063 00064 CMainObj::~CMainObj() 00065 { 00066 // Note that calling kr_Controller_stop is unnecessary since 00067 // destruction is quite sufficient for stopping. 00068 kr_Controller_destroy(client); 00069 } 00070 00071 void CMainObj::ConstructL() // activates the object 00072 { 00073 // Invokes AppContextReady upon completion. 00074 ac_AppContext_PlatInitAsyncL(ac_get_global_AppContext(), *this); 00075 } 00076 00077 void CMainObj::AppContextReady(TInt aError) 00078 { 00079 logt("app context ready"); 00080 00081 if (aError) { 00082 er_log_symbian(er_FATAL, aError, "error in app ctx async init"); 00083 return; // not reached 00084 } 00085 00086 GError* localError = NULL; 00087 00088 client = kr_Controller_new(&localError); 00089 if (!client) { 00090 er_log_gerror(er_FATAL|er_FREE, localError, "error in client creation"); 00091 return; // not reached 00092 } 00093 00094 if (!kr_Controller_start(client, &localError)) { 00095 kr_Controller_destroy(client); 00096 er_log_gerror(er_FATAL|er_FREE, localError, "error starting client"); 00097 return; // not reached 00098 } 00099 } 00100 00101 static TInt MainLoop() 00102 { 00103 globalLoop = new CActiveSchedulerWait; 00104 if (!globalLoop) { 00105 return KErrNoMemory; 00106 } 00107 00108 CMainObj* mainObj = NULL; 00109 TRAPD(errCode, mainObj = CMainObj::NewL()); 00110 if (errCode) { 00111 delete globalLoop; 00112 return errCode; 00113 } 00114 00115 // Will not return unless/until explicitly stopped by 00116 // ShutdownApplication. 00117 globalLoop->Start(); 00118 00119 delete globalLoop; 00120 delete mainObj; 00121 00122 return 0; 00123 } 00124 00125 static TInt SubMain() 00126 { 00127 TInt errCode = 0; 00128 errCode = cl2GlobalInit(); 00129 if (errCode) 00130 return errCode; 00131 TRAPD(leaveCode, errCode = MainLoop()); 00132 if (leaveCode) { 00133 assert(0 && "leave where not expected"); 00134 } 00135 cl2GlobalCleanup(); 00136 return errCode; 00137 } 00138 00139 // On Symbian at least we might want to name this process so that it 00140 // is easier to identify and kill. But actually we should have a 00141 // sensible name to begin with, since we should get something like 00142 // ekern.exe[100041af]0001, where we have the executable name, UID, 00143 // and instance number. 00144 // 00145 // Apparently also some Open C functions require that they are running 00146 // under a TRAP. Naturally then a cleanup stack is surely also 00147 // required. At present we are defining an E32Main rather than a main, 00148 // so we shall do things explicitly. 00149 // 00150 // In the Symbian case we must create an active scheduler within which 00151 // to run; our event delivery mechanism requires this, and most 00152 // certainly a lot of our system access code requires it. Note that to 00153 // start the event loop, we must call CActiveScheduler::Start(). 00154 GLDEF_C TInt E32Main() 00155 { 00156 TInt errCode = 0; 00157 __UHEAP_MARK; 00158 WITH_CLEANUP_STACK(WITH_ACTIVE_SCHEDULER(errCode = SubMain())); 00159 __UHEAP_MARKEND; 00160 return errCode; 00161 } 00162 00163 /** 00164 00165 epoc-main.cpp 00166 00167 Copyright 2009 Helsinki Institute for Information Technology (HIIT) 00168 and the authors. All rights reserved. 00169 00170 Authors: Tero Hasu <tero.hasu@hut.fi> 00171 00172 Permission is hereby granted, free of charge, to any person 00173 obtaining a copy of this software and associated documentation files 00174 (the "Software"), to deal in the Software without restriction, 00175 including without limitation the rights to use, copy, modify, merge, 00176 publish, distribute, sublicense, and/or sell copies of the Software, 00177 and to permit persons to whom the Software is furnished to do so, 00178 subject to the following conditions: 00179 00180 The above copyright notice and this permission notice shall be 00181 included in all copies or substantial portions of the Software. 00182 00183 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00184 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00185 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00186 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 00187 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 00188 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00189 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00190 SOFTWARE. 00191 00192 **/
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:55 2011 by Doxygen 1.6.1