DummySpawnManager.h

00001 /*
00002  *  Phusion Passenger - http://www.modrails.com/
00003  *  Copyright (C) 2008  Phusion
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; version 2 of the License.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 #ifndef _PASSENGER_DUMMY_SPAWN_MANAGER_H_
00019 #define _PASSENGER_DUMMY_SPAWN_MANAGER_H_
00020 
00021 // TODO: make this path not hardcoded
00022 #define DUMMY_REQUEST_HANDLER_EXECUTABLE "/home/hongli/Projects/passenger/benchmark/DummyRequestHandler"
00023 
00024 #include <string>
00025 
00026 #include <sys/types.h>
00027 #include <sys/wait.h>
00028 #include <cstdio>
00029 #include <unistd.h>
00030 #include <errno.h>
00031 
00032 #include "Application.h"
00033 #include "Exceptions.h"
00034 
00035 namespace Passenger {
00036 
00037 using namespace std;
00038 
00039 /**
00040  * A dummy SpawnManager replacement for testing/debugging purposes.
00041  *
00042  * This class implements a dummy spawn manager, and is 100% interface-compatible with
00043  * SpawnManager. This spawn manager will spawn <tt>benchmark/DummyRequestHandler</tt>,
00044  * which is probably the fastest possible implementation of a request handler. The purpose
00045  * of this class to benchmark the performance of the Apache module (i.e. not benchmarking
00046  * the Ruby request handler or Rails itself).
00047  *
00048  * This header file is not used by default. Define the macro <tt>PASSENGER_USE_DUMMY_SPAWN_MANAGER</tt>
00049  * to make ApplicationPool use DummySpawnManager instead of SpawnManager.
00050  *
00051  * Of course, don't forget to compile benchmark/DummyRequestHandler!
00052  *
00053  * @ingroup Support
00054  */
00055 class DummySpawnManager {
00056 public:
00057         ApplicationPtr spawn(const string &appRoot, const string &user = "", const string &group = "") {
00058                 int fds[2];
00059                 pid_t pid;
00060                 
00061                 if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
00062                         throw SystemException("Cannot create a Unix socket", errno);
00063                 }
00064                 pid = fork();
00065                 if (pid == 0) {
00066                         pid = fork();
00067                         if (pid == 0) {
00068                                 dup2(fds[0], STDIN_FILENO);
00069                                 close(fds[0]);
00070                                 close(fds[1]);
00071                                 execlp(DUMMY_REQUEST_HANDLER_EXECUTABLE, DUMMY_REQUEST_HANDLER_EXECUTABLE, NULL);
00072                                 int e = errno;
00073                                 fprintf(stderr, "Unable to run %s: %s\n", DUMMY_REQUEST_HANDLER_EXECUTABLE, strerror(e));
00074                                 fflush(stderr);
00075                                 _exit(1);
00076                         } else if (pid == -1) {
00077                                 perror("Cannot fork a new process");
00078                                 fflush(stderr);
00079                                 _exit(1);
00080                         } else {
00081                                 _exit(0);
00082                         }
00083                 } else if (pid == -1) {
00084                         close(fds[0]);
00085                         close(fds[1]);
00086                         throw SystemException("Cannot fork a new process", errno);
00087                 } else {
00088                         close(fds[0]);
00089                         waitpid(pid, NULL, 0);
00090                         return ApplicationPtr(new Application(appRoot, pid, fds[1]));
00091                 }
00092         }
00093         
00094         pid_t getServerPid() const {
00095                 return 0;
00096         }
00097 };
00098 
00099 } // namespace Passenger
00100 
00101 #endif /* _PASSENGER_DUMMY_SPAWN_MANAGER_H_ */

Generated on Wed Apr 30 00:07:01 2008 for Passenger by  doxygen 1.5.3