Passenger: DummySpawnManager.h Source File

- Main Page
- Modules
- Classes
- Files

- File List

# 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_ */