socketd_cppsp.C 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. * */
  13. #include <cpoll/cpoll.H>
  14. #include <unistd.h>
  15. #include <iostream>
  16. #include <socketd.H>
  17. #include <signal.h>
  18. #include <socketd_client.H>
  19. #include <cppsp/page.H>
  20. #include <cppsp/cppsp_cpoll.H>
  21. #include <cppsp/common.H>
  22. #include "server.C"
  23. using namespace std;
  24. using namespace socketd;
  25. using namespace CP;
  26. using namespace cppsp;
  27. string rootDir;
  28. void parseArgs(int argc, char** argv, const function<void(char*, const function<char*()>&)>& cb) {
  29. int i = 1;
  30. function<char*()> func = [&]()->char*
  31. {
  32. if(i+1>=argc)return NULL;
  33. return argv[(++i)];
  34. };
  35. for (; i < argc; i++) {
  36. if (argv[i][0] == '\x00') continue;
  37. if (argv[i][0] == '-') {
  38. cb(argv[i] + 1, func);
  39. } else {
  40. cb(NULL, [argv,i]()
  41. { return argv[i];});
  42. }
  43. }
  44. }
  45. int main(int argc, char** argv) {
  46. cout << "started child #" << getpid() << endl;
  47. srand(int(getpid())^(int)time(NULL));
  48. {
  49. char cwd[255];
  50. if(getcwd(cwd,255)==NULL) throw runtime_error(strerror(errno));
  51. rootDir=cwd;
  52. }
  53. CP::Poll p;
  54. vector<string> cxxopts;
  55. vector<const char*> modules;
  56. parseArgs(argc, argv,
  57. [&](char* name, const std::function<char*()>& getvalue)
  58. {
  59. if(strcmp(name,"r")==0) {
  60. rootDir=getvalue();
  61. } else if(strcmp(name,"c")==0) {
  62. cxxopts.push_back(getvalue());
  63. } else if(strcmp(name,"m")==0) {
  64. modules.push_back(getvalue());
  65. }
  66. });
  67. cppspServer::Server srv(rootDir.c_str());
  68. auto& v=CXXOpts(srv.mgr);
  69. v.insert(v.end(),cxxopts.begin(),cxxopts.end());
  70. cxxopts.clear();
  71. MemoryPool mp(sizeof(cppspServer::handler));
  72. struct {
  73. CP::Poll& p;
  74. MemoryPool& mp;
  75. cppspServer::Server& srv;
  76. void operator()(socketd_client& cl, Socket* s, int64_t id) {
  77. if(s==NULL)kill(getpid(),9);
  78. cl.ack(id);
  79. cppspServer::handler* hdlr=new (mp.alloc())
  80. cppspServer::handler(srv,p,*s);
  81. hdlr->allocator=&mp;
  82. }
  83. } cb {p, mp, srv};
  84. int modsLeft;
  85. struct {
  86. int& modsLeft;
  87. CP::Poll& p;
  88. Delegate<void(socketd_client& cl, Socket* s, int64_t id)> cb;
  89. void operator()() {
  90. if(--modsLeft == 0) {
  91. new socketd_client(p,cb);
  92. }
  93. }
  94. } afterModuleLoad {modsLeft,p,&cb};
  95. struct {
  96. const char* s;
  97. Delegate<void()> afterModuleLoad;
  98. void operator()(void*,exception* ex) {
  99. if(ex!=NULL) {
  100. fprintf(stderr,"error loading module %s: %s\n",s,ex->what());
  101. cppsp::CompileException* ce = dynamic_cast<cppsp::CompileException*>(ex);
  102. if (ce != NULL) {
  103. printf("%s\n",ce->compilerOutput.c_str());
  104. }
  105. }
  106. afterModuleLoad();
  107. }
  108. } moduleCB[modules.size()];
  109. modsLeft=modules.size();
  110. for(int ii=0;ii<(int)modules.size();ii++) {
  111. moduleCB[ii].s=modules[ii];
  112. moduleCB[ii].afterModuleLoad=&afterModuleLoad;
  113. srv.loadModule(p,modules[ii],&moduleCB[ii]);
  114. }
  115. if(modules.size()==0) new socketd_client(p,&cb);
  116. p.loop();
  117. }