Core.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 $Header$
00004 
00005 */
00006 
00007 #include "Error.h"
00008 #include "Config.h"
00009 #include "ServiceBase.h"
00010 #include "Timer.h"
00011 #include "Forth.h"
00012 #include "Syslog.h"
00013 
00014 #include "Core.h"
00015 
00016 Core::ServiceList Core::_services;
00017 
00018 // Public methods.
00019 
00020 int Core::init()
00021 {
00022   CONFIG();
00023   SYSLOG();
00024   FORTH();
00025   CORE();
00026 
00027   return OK;
00028 }
00029 
00030 int Core::dispatch()
00031 {
00032   int res;
00033 
00034   if (FAILED(res = Object::deletePostponed()))
00035     return ERROR_BACKTRACE(res);
00036 
00037   if (FAILED(res = Timer::shootTimers()))
00038     return ERROR_BACKTRACE(res);
00039 
00040   if (FAILED(res = poll()))
00041     return ERROR_BACKTRACE(res);
00042 
00043   EMIT(idle);
00044 
00045   return OK;
00046 }
00047 
00048 int Core::main()
00049 {
00050   int res = OK;
00051 
00052   while (!_quit && SUCCEEDED(res = dispatch()));
00053   if (FAILED(res))
00054     return ERROR_BACKTRACE(res);
00055 
00056   return OK;
00057 }
00058 
00059 int Core::registerService(const String &name, Fabrica fabrica,
00060                           MethodInstancesNumber instancesNumberLimit, MethodInstancesNumber instancesNumber,
00061                           MethodManual manual)
00062 {
00063   if (!instancesNumberLimit || !instancesNumber)
00064     return ERROR(MSG_NULL_POINTER);
00065 
00066   ServiceList::const_iterator f = _services.find(name);
00067 
00068   if (f != _services.end())
00069     return ERROR(MSG_CORE_SERVICE_ALREADY_REGISTERED, CSTRING(name));
00070 
00071   SpawnInfo si = {fabrica, instancesNumberLimit, instancesNumber, manual};
00072 
00073   _services[name] = si;
00074 
00075   return OK;
00076 }
00077 
00078 int Core::spawn(const String &serviceName, const ValueList &params, ServiceBase **instance)
00079 {
00080   ServiceList::const_iterator f = _services.find(serviceName);
00081 
00082   if (f == _services.end())
00083     return ERROR(MSG_CORE_SERVICE_UNKNOWN, CSTRING(serviceName));
00084 
00085   unsigned int insLimit = f->second.instancesNumberLimit();
00086   unsigned int insNum = f->second.instancesNumber();
00087 
00088   if (insLimit > 0 && insNum + 1 > insLimit)
00089     return ERROR(MSG_CORE_SERVICE_NSTANCES_LIMIT_EXCEEDED, CSTRING(serviceName), insLimit, insNum);
00090 
00091   ServiceBase *inst;
00092 
00093   DEBUG("Spawinig service '%s'.", CSTRING(serviceName));
00094   if (!(inst = f->second.fabrica(params)))
00095     return ERROR(MSG_CORE_SERVICE_CANNOT_SPAWN, CSTRING(serviceName));
00096   DEBUG("Service '%s' spawned successfully.", CSTRING(serviceName));
00097 
00098   if (instance)
00099     *instance = inst;
00100 
00101   return OK;
00102 }
00103 
00104 int Core::spawn(const String &serviceName, ServiceBase **instance)
00105 {
00106   int res;
00107 
00108   if (FAILED(res = spawn(serviceName, ValueList(), instance)))
00109     return ERROR_BACKTRACE(res);
00110 
00111   return OK;
00112 }
00113 
00114 int Core::fork(const ObjectId id, ServiceBase **instance)
00115 {
00116   ServiceBase *inst, *newInst;
00117   int res;
00118 
00119   if (FAILED(res = Object::get(id, (Object **)(&inst))))
00120     return ERROR_BACKTRACE(res);
00121 
00122   if (!inst->forkable())
00123     return ERROR(MSG_CORE_SERVICE_NOT_FORKABLE, CSTRING(inst->name()));
00124 
00125   DEBUG("Forking service '%s'.", CSTRING(inst->name()));
00126   if (!(newInst = inst->fork()))
00127     return ERROR(MSG_CORE_SERVICE_CANNOT_FORK, CSTRING(inst->name()));
00128   DEBUG("Service '%s' forked successfully.", CSTRING(inst->name()));
00129 
00130   if (instance)
00131     *instance = newInst;
00132 
00133   return OK;
00134 }
00135 
00136 int Core::kill(ServiceBase *instance)
00137 {
00138   if (!instance)
00139     return ERROR(MSG_NULL_POINTER);
00140 
00141   int res;
00142 
00143   if (FAILED(res = instance->kill()))
00144     return ERROR_BACKTRACE(res);
00145 
00146   return OK;
00147 }
00148 
00149 int Core::kill(const ObjectId id)
00150 {
00151   Object *obj;
00152   ServiceBase *instance;
00153   int res;
00154 
00155   if (FAILED(res = Object::get(id, &obj)))
00156     return ERROR_BACKTRACE(res);
00157 
00158   if (!(instance = queryInterface<ServiceBase>(obj)))
00159     return ERROR(MSG_CORE_UNEXPECTED_ID, id);
00160 
00161   if (FAILED(res = kill(instance)))
00162     return ERROR_BACKTRACE(res);
00163 
00164   return OK;
00165 }
00166 
00167 int Core::killAll(const String &serviceName)
00168 {
00169   ObjectList::iterator i = Object::_objects.begin();
00170   ObjectList::iterator e = Object::_objects.end();
00171   ServiceBase *inst;
00172   int res;
00173 
00174   while (i != e) {
00175     inst = queryInterface<ServiceBase>(i->second);
00176     if (inst && inst->name() == serviceName) {
00177       if (FAILED(res = inst->kill()))
00178         ERROR_BACKTRACE(res);
00179     }
00180     ++i;
00181   }
00182 
00183   return OK;
00184 }
00185 
00186 int Core::suspend(const ObjectId id)
00187 {
00188   Object *obj;
00189   int res;
00190 
00191   if (FAILED(res = Object::get(id, &obj)))
00192     return ERROR_BACKTRACE(res);
00193 
00194   if (FAILED(res = obj->suspend()))
00195     return ERROR_BACKTRACE(res);
00196 
00197   return OK;
00198 }
00199 
00200 int Core::suspendAll(const String &serviceName)
00201 {
00202   ObjectList::iterator i = Object::_objects.begin();
00203   ObjectList::iterator e = Object::_objects.end();
00204   ServiceBase *inst;
00205   int res;
00206 
00207   while (i != e) {
00208     inst = queryInterface<ServiceBase>(i->second);
00209     if (inst && inst->name() == serviceName) {
00210       if (FAILED(res = inst->suspend()))
00211         ERROR_BACKTRACE(res);
00212     }
00213     ++i;
00214   }
00215 
00216   return OK;
00217 }
00218 
00219 int Core::resume(const ObjectId id)
00220 {
00221   Object *obj;
00222   int res;
00223 
00224   if (FAILED(res = Object::get(id, &obj)))
00225     return ERROR_BACKTRACE(res);
00226 
00227   if (FAILED(res = obj->resume()))
00228       return ERROR_BACKTRACE(res);
00229 
00230   return OK;
00231 }
00232 
00233 int Core::resumeAll(const String &serviceName)
00234 {
00235   ObjectList::iterator i = Object::_objects.begin();
00236   ObjectList::iterator e = Object::_objects.end();
00237   ServiceBase *inst;
00238   int res;
00239 
00240   while (i != e) {
00241     inst = queryInterface<ServiceBase>(i->second);
00242     if (inst && inst->name() == serviceName) {
00243       if (FAILED(res = inst->resume()))
00244         ERROR_BACKTRACE(res);
00245     }
00246     ++i;
00247   }
00248 
00249   return OK;
00250 }
00251 
00252 int Core::suspendTimers()
00253 {
00254   ObjectList::iterator i = Object::_objects.begin();
00255   ObjectList::iterator e = Object::_objects.end();
00256   Timer *timer;
00257   int res;
00258 
00259   while (i != e) {
00260     if ((timer = queryInterface<Timer>(i->second)))
00261       if (FAILED(res = timer->suspend()))
00262         ERROR_BACKTRACE(res);
00263     ++i;
00264   }
00265 
00266   return OK;
00267 }
00268 
00269 int Core::resumeTimers()
00270 {
00271   ObjectList::iterator i = Object::_objects.begin();
00272   ObjectList::iterator e = Object::_objects.end();
00273   Timer *timer;
00274   int res;
00275 
00276   while (i != e) {
00277     if ((timer = queryInterface<Timer>(i->second)))
00278       if (FAILED(res = timer->resume()))
00279         ERROR_BACKTRACE(res);
00280     ++i;
00281   }
00282 
00283   return OK;
00284 }
00285 
00286 int Core::notify(ServiceBase *instance, const ValueList &params)
00287 {
00288   if (!instance)
00289     return ERROR(MSG_NULL_POINTER);
00290 
00291   int res;
00292 
00293   if (FAILED(res = instance->notify(params)))
00294     return ERROR_BACKTRACE(res);
00295 
00296   return OK;
00297 }
00298 
00299 int Core::notify(const ObjectId id, const ValueList &params)
00300 {
00301   Object *obj;
00302   ServiceBase *instance;
00303   int res;
00304 
00305   if (FAILED(res = Object::get(id, &obj)))
00306     return ERROR_BACKTRACE(res);
00307 
00308   if (!(instance = queryInterface<ServiceBase>(obj)))
00309     return ERROR(MSG_CORE_UNEXPECTED_ID, id);
00310 
00311   if (FAILED(res = notify(instance, params)))
00312     return ERROR_BACKTRACE(res);
00313 
00314   return OK;
00315 }
00316 
00317 int Core::notifyAll(const String &serviceName, const ValueList &params)
00318 {
00319   ObjectList::iterator i = Object::_objects.begin();
00320   ObjectList::iterator e = Object::_objects.end();
00321   ServiceBase *inst;
00322   int res;
00323 
00324   while (i != e) {
00325     inst = queryInterface<ServiceBase>(i->second);
00326     if (inst && inst->name() == serviceName) {
00327       if (FAILED(res = inst->notify(params)))
00328         ERROR_BACKTRACE(res);
00329     }
00330     ++i;
00331   }
00332 
00333   return OK;
00334 }
00335 
00336 int Core::quit()
00337 {
00338   _quit = true;
00339   return OK;
00340 }
00341 
00342 int Core::listServices(String &text)
00343 {
00344   ServiceList::const_iterator i = _services.begin();
00345   ServiceList::const_iterator e = _services.end();
00346   String line;
00347   unsigned int n = 1;
00348 
00349   line.sprintf("%s%6s\t%5s\t%6s\t%-16s%s", String::eol(), "#", "LIMIT", "RUNNED", "NAME", String::eol());
00350   text = CORE_COLOR_TITLE(line);
00351   while (i != e) {
00352     if (i->second.instancesNumberLimit() != 0)
00353       line.sprintf("%6d\t%5u\t%6u\t%-16s%s", n, i->second.instancesNumberLimit(), i->second.instancesNumber(), CSTRING(i->first), String::eol());
00354     else
00355       line.sprintf("%6d\t%5s\t%6u\t%-16s%s", n, "No", i->second.instancesNumber(), CSTRING(i->first), String::eol());
00356     text += line;
00357     ++i;
00358     ++n;
00359   }
00360 
00361   return OK;
00362 }
00363 
00364 // Private methods.
00365 
00366 Core::Core() : Poller(), Singleton<Core>()
00367 {
00368   _quit = false;
00369 }
00370 
00371 Core::~Core()
00372 {
00373 }

Generated on Thu Sep 6 20:11:25 2007 for Pylon Application Platform by  doxygen 1.5.1