DummySpawnManager.h

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

Generated on Fri Jan 23 08:28:57 2009 for Passenger by  doxygen 1.4.7