Commenting, adding Doxyfile, enhancing Makefile

This commit is contained in:
Yann Weber 2019-07-01 02:21:36 +02:00
commit ebb01bb82e
6 changed files with 2656 additions and 10 deletions

2494
Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,17 @@
all:
+make -C src
.PHONY: clean
doc:
doxygen
clean:
make -C src clean
.PHONY: distclean clean __pycache__clean doc
distclean: __pycache__clean
-make -C src distclean;\
rm -Rvf doc/latex doc/html doc/man
clean: __pycache__clean
-make -C src clean;\
__pycache__clean:
rm -Rvf __pycache__

View file

@ -4,18 +4,22 @@ CFLAGS=-c -Wall `python3-config --includes`
LDFLAGS=`python3-config --libs` -lfcgi
#LDFLAGS= -L`python3-config --configdir` `python3-config --libs` -lfcgi
BIN=pyfcgi
SRCS=$(wildcard *.c)
OBJS=$(SRCS:.c=.o)
all: pyfcgi
all: $(BIN)
pyfcgi: $(OBJS)
$(BIN): $(OBJS)
$(CC) $(LDFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -o $@ $<
.PHONY: clean
.PHONY: clean distclean
distclean: clean
-rm -v $(BIN)
clean:
@rm -v $(OBJS)
-rm -v $(OBJS)

View file

@ -16,6 +16,19 @@
* You should have received a copy of the GNU Affero General Public License
* along with PyFCGI. If not, see <http://www.gnu.org/licenses/>.
*/
/**@defgroup processes Process organisation of PyFCGI
*
* PyFCGI is organised in three layer :
* A @ref main_proc : simple, that keep running and spawn a
* @ref work_master_proc . This process handles @ref worker_process creation
* and try to maintain a pool able to reply efficiently to CGI requests.
*/
/**@defgroup main_proc Main process
* @brief The main process in the @ref main() function
* @ingroup processes
*/
#include <fcgi_stdio.h> /* fcgi library; put it first*/
#include <unistd.h>
@ -76,7 +89,7 @@ int main(int argc, char **argv)
}
else if(!child)
{
responder_loop(py_entrypoint, MAX_REQS, 1, 20);
responder_loop(py_entrypoint, MAX_REQS, 1, 30);
exit((unsigned char)-1);
}
waitpid(child, &child_ret, 0);
@ -94,3 +107,62 @@ int main(int argc, char **argv)
closelog();
free(ident);
}
/**@mainpage PyFCGI
* @section main_what What is PyFCGI ?
* PyFCGI is a simple python3 fastcgi runner.
*
* Usage : *PY_ENTRYPOINT='foo' spawn-fcgi -d . -n src/pyfcgi -p 9000 -a 127.0.0.1*
*
* To run foo.entrypoint() python function.
*
* @subsection main_how_use How to use it ?
*
* @warning For the moment PyFCGI is under heavy developpement and in early
* stage. Everything will change ;o)
*
* PyFCGI should be runned with spawn-fcgi (or something similar), allowing
* to configure & forward environnement variables to libFCGI.
*
* For the moment no configuration files exists. You have to pass a
* PY_ENTRYPOINT containing an importable python module containing an
* entrypoint() (no arguments for the moment) function.
*
* When called this function will have to send valid CGI data to the webserver
* using sys.stdin (the print() function for exemple) like :
*<code>Content-type: text/html\\r\\n\\r\\nHello world !\\n</code>
*
* The function will have access to updated CGI os.environ containing
* all informations about a request
*
* @subsubsection main_how_use_syslog Logging, using syslog
*
* Right now PyFCGI uses syslog() to log stuff using a pyfcgi ident.
* PyFCGI logs can be filtered using /etc/rsyslog.d/pyfcgi.conf :
*
<pre>
if ($programname contains 'pyfcgi') then {
-/var/log/pyfcgi/pyfcgi.log
stop
}
</pre>
*
* @subsubsection main_how_use_hardcode Hardcoded stuffs
*
* Right now there is a lot of hardcodd stuff. Fortunatly a vast majority
* is in @ref main.c like the minimum and maximum number of workers, or
* the number of requests before a worker restart. Some timers and stuff
* are harcoded but should not in @ref pyworker.c & @ref responder.c
*
* @subsection main_how_works How it works ?
*
* - @ref processes
* - @ref main_proc
* - @ref work_master_proc
* - @ref worker_process
*
* @subsection main_how_todo TODO
* @todo Add another logging facility
* @todo Add a configuration mecanism
*/

View file

@ -16,6 +16,44 @@
* You should have received a copy of the GNU Affero General Public License
* along with PyFCGI. If not, see <http://www.gnu.org/licenses/>.
*/
/**@defgroup worker_process Worker processes
* @brief Processus handling python execution with @ref work() function
*
* This kind of process are @ref spawn() by a @ref work_master_proc
* @section Running Python
* Running embed python in FCGI mean serving multiple requests with a single
* python process, meaning :
* - environnement variable of the living Python process need to be updated
* - we need a way to communicate with python code
*
* @subsection worker_proc_ipc Communicating with python
* sys.stdout & sys.stderr will be used to communicate in python. Shortly
* after python initialize @ref update_python_fd() update these two file
* objects with freshly created pipes.
*
* @subsubsection worker_proc_ipc_piper The piper process
*
* When a request arrive, the worker process fork again in a @ref worker_piper() child
* process that will read the two pipes. Sending stdout to FCGI using printf
* and stderr to syslog.
*
* @subsection worker_proc_environ Updating os.environ
* os.environ is a special kind of dictionnary, automatically calling
* os.putenv() function. This function will attempt (and succeed) to update
* the real process environnement, making a nasty conflict with libfcgi (trying
* to free an environnement it did not create anymore...).
*
* The os.environ is replaced by a simple python dict by @ref update_pyenv()
* once a request.
*
* @see update_python_path()
*
* @ingroup processes
* @ingroup work_master_proc
*/
/**@file pyworker.h
* @ingroup worker_process
*/
#ifndef _PYWORKER__H___
#define _PYWORKER__H___
@ -48,6 +86,7 @@ typedef unsigned long int pywrkid_t;
/**@brief the function that initialize the python worker
* @ingroup worker_process
* @param char* python_entrypoint a path to a python entrypoint
* @param int worker uid
* @param int semid for FCGI access
@ -58,6 +97,7 @@ int work(char*, int, int, int);
/**@brief function for a subprocess designed to read stdin & stdout from
* python & forward them to syslog or FCGI
* @ingroup worker_process
* @param int worker id
* @param int request id
* @param int pystdout
@ -87,12 +127,14 @@ void fetch_pyflush(PyObject**, PyObject**);
void update_python_path();
/**@brief Create two pipes for stdout & stderr
* @ingroup worker_process
* @params int[2] pystdout
* @params int[2] pystderr
*/
void update_python_fd(int[2], int[2]);
/**@brief Clear then update python sys.environ using current FCI environ
* @ingroup worker_process
* @note The environ has to be set without a call to os.putenv, the problem
* is that the os.environ is a special mapping calling putenv on setitem...
* For these reason the os.environ will be replaced by a new dict instance for

View file

@ -16,6 +16,28 @@
* You should have received a copy of the GNU Affero General Public License
* along with PyFCGI. If not, see <http://www.gnu.org/licenses/>.
*/
/**@defgroup work_master_proc Worker handler process
* @brief This process use the @ref responder_loop() function as "main" function
*
* @section work_master_spawn Spawning workers
* This subprocess handle worker spawning using @ref spawn(). A POSIX semaphore
* allow to know when the worker pool is idle or not :
*
* @subsection work_master_spawn_sem Semaphore idle & busy detection
* When a new worker is ready (idle) it add 1 to the semaphore, when processing
* a request it substract 1 to the semaphore (done in @ref work() function in
* @ref worker_process )
*
* When semtimedop blocks on wait_for_zero operation it means that the pool is
* idle. Instead, if the semtimedop returns imediately it means a new worker
* can be spawned.
*
* @ingroup processes
* @ingroup main_proc
*/
/**@file responder.h
* @ingroup work_master_proc
*/
#ifndef _RESPONDER__H___
#define _RESPONDER__H___
#include "config.h"
@ -40,7 +62,7 @@ extern int pyfcgi_semid;
void init_context();
/**@brief The responder loop
*
* @ingroup work_master_proc
* The main function of the fcgi app fork child
* @param int max_requests : exit normally after this number of requests. If
* 0 given never exit.
@ -55,7 +77,7 @@ int responder_loop(char *py_entrypoint, unsigned int max_reqs,
/**@brief Spawn a worker given an entrypoint
*
* @ingroup work_master_proc
* Spawn a new worker process and prepare ENV & request forwarding
* @param char* python_entrypoint a path to a python entrypoint
* @param int worker uid
@ -66,12 +88,14 @@ int responder_loop(char *py_entrypoint, unsigned int max_reqs,
pid_t spawn(char*, int, int, int);
/**@brief Generate a new semaphore from given key
* @ingroup work_master_proc
* @note set pyfcgi_semid
* @return int semid
*/
int new_semaphore();
/**@brief Exit after closing all stuff like semaphores
* @ingroup work_master_proc
*/
void clean_exit(int);