- Main Page
- Classes
- Files

- File List

# src/process.cpp

    00001 // ---------------------------------------------------------------------
    00002 // pion:  a Boost C++ framework for building lightweight HTTP interfaces
    00003 // ---------------------------------------------------------------------
    00004 // Copyright (C) 2007-2012 Cloudmeter, Inc.  (http://www.cloudmeter.com)
    00005 //
    00006 // Distributed under the Boost Software License, Version 1.0.
    00007 // See http://www.boost.org/LICENSE_1_0.txt
    00008 //
    00009
    00010 #include <signal.h>
    00011 #ifdef _MSC_VER
    00012     #include <windows.h>
    00013 #else
    00014     #include <fcntl.h>
    00015     #include <unistd.h>
    00016     #include <sys/stat.h>
    00017 #endif
    00018
    00019 #include <pion/config.hpp>
    00020 #include <pion/process.hpp>
    00021
    00022
    00023 namespace pion {    // begin namespace pion
    00024
    00025 // static members of process
    00026
    00027 boost::once_flag                process::m_instance_flag = BOOST_ONCE_INIT;
    00028 process::config_type *process::m_config_ptr = NULL;
    00029
    00030
    00031 // process member functions
    00032
    00033 void process::shutdown(void)
    00034 {
    00035     config_type& cfg = get_config();
    00036     boost::mutex::scoped_lock shutdown_lock(cfg.shutdown_mutex);
    00037     if (! cfg.shutdown_now) {
    00038         cfg.shutdown_now = true;
    00039         cfg.shutdown_cond.notify_all();
    00040     }
    00041 }
    00042
    00043 void process::wait_for_shutdown(void)
    00044 {
    00045     config_type& cfg = get_config();
    00046     boost::mutex::scoped_lock shutdown_lock(cfg.shutdown_mutex);
    00047     while (! cfg.shutdown_now)
    00048         cfg.shutdown_cond.wait(shutdown_lock);
    00049 }
    00050
    00051 void process::create_config(void)
    00052 {
    00053     static config_type UNIQUE_PION_PROCESS_CONFIG;
    00054     m_config_ptr = &UNIQUE_PION_PROCESS_CONFIG;
    00055 }
    00056
    00057
    00058
    00059 #ifdef _MSC_VER
    00060
    00061 BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
    00062 {
    00063     switch(ctrl_type) {
    00064         case CTRL_C_EVENT:
    00065         case CTRL_BREAK_EVENT:
    00066         case CTRL_CLOSE_EVENT:
    00067         case CTRL_SHUTDOWN_EVENT:
    00068             process::shutdown();
    00069             return TRUE;
    00070         default:
    00071             return FALSE;
    00072     }
    00073 }
    00074
    00075 void process::initialize(void)
    00076 {
    00077     SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
    00078 }
    00079
    00080 void process::daemonize(void)
    00081 {
    00082     // not supported
    00083 }
    00084
    00085 #else   // NOT #ifdef _MSC_VER
    00086
    00087 void handle_signal(int sig)
    00088 {
    00089     process::shutdown();
    00090 }
    00091
    00092 void process::initialize(void)
    00093 {
    00094     signal(SIGPIPE, SIG_IGN);
    00095     signal(SIGCHLD, SIG_IGN);
    00096     signal(SIGTSTP, SIG_IGN);
    00097     signal(SIGTTOU, SIG_IGN);
    00098     signal(SIGTTIN, SIG_IGN);
    00099     signal(SIGHUP, SIG_IGN);
    00100     signal(SIGINT, handle_signal);
    00101     signal(SIGTERM, handle_signal);
    00102 }
    00103
    00104 void process::daemonize(void)
    00105 {
    00106     // adopted from "Unix Daemon Server Programming"
    00107     // http://www.enderunix.org/docs/eng/daemon.php
    00108
    00109     // return early if already running as a daemon
    00110     if(getppid()==1) return;
    00111
    00112     // for out the process
    00113     int i = fork();
    00114     if (i<0) exit(1);   // error forking
    00115     if (i>0) exit(0);   // exit if parent
    00116
    00117     // child (daemon process) continues here after the fork...
    00118
    00119     // obtain a new process group
    00120     setsid();
    00121
    00122     // close all descriptors
    00123     for (i=getdtablesize();i>=0;--i) close(i);
    00124
    00125     // bind stdio to /dev/null (ignore errors)
    00126     i=open("/dev/null",O_RDWR);
    00127     if (i != -1) {
    00128         if (dup(i) == -1) {}
    00129         if (dup(i) == -1) {}
    00130     }
    00131
    00132     // restrict file creation mode to 0750
    00133     umask(027);
    00134 }
    00135
    00136 #endif  // #ifdef _MSC_VER
    00137
    00138 }   // end namespace pion