summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Bühler <stbuehler@web.de>2010-08-11 22:28:19 +0200
committerStefan Bühler <stbuehler@web.de>2010-08-11 22:28:19 +0200
commitc39c6ee64bbae9fd81fb4da168dfa7583c1af703 (patch)
tree257cd3f621ceec471887862ce120ede18b3c63d0
downloadlibmanda-c39c6ee64bbae9fd81fb4da168dfa7583c1af703.tar.gz
libmanda-c39c6ee64bbae9fd81fb4da168dfa7583c1af703.zip
Initial commit
-rw-r--r--.gitignore13
-rw-r--r--CMakeLists.txt56
-rw-r--r--COPYING22
-rw-r--r--Makefile.am14
-rw-r--r--configure.ac54
-rw-r--r--libmanda-config.h.cmake6
-rw-r--r--libmanda-protocol.h82
-rw-r--r--libmanda.c10
-rw-r--r--libmanda.h125
-rw-r--r--libmanda.pc.in11
10 files changed, 393 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6e218b4
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.guess
+config.sub
+configure
+depcomp
+install-sh
+libmanda-config.h.in
+ltmain.sh
+m4/
+missing
+*~
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..abe55ca
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,56 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6.0 FATAL_ERROR)
+
+cmake_policy(VERSION 2.6.0)
+
+SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+
+INCLUDE(CheckIncludeFiles)
+INCLUDE(CheckLibraryExists)
+INCLUDE(FindPkgConfig)
+
+MACRO(ADD_TARGET_PROPERTIES _target _name _properties)
+ SET(_properties ${ARGV})
+ LIST(REMOVE_AT _properties 0)
+ LIST(REMOVE_AT _properties 0)
+ GET_TARGET_PROPERTY(_old_properties ${_target} ${_name})
+ #MESSAGE("adding property to ${_target} ${_name}: ${_properties}")
+ IF(NOT _old_properties)
+ # in case it's NOTFOUND
+ SET(_old_properties)
+ ELSE(NOT _old_properties)
+ SET(_old_properties "${_old_properties} ")
+ ENDIF(NOT _old_properties)
+ SET_TARGET_PROPERTIES(${_target} PROPERTIES ${_name} "${_old_properties}${_properties}")
+ENDMACRO(ADD_TARGET_PROPERTIES)
+
+PROJECT(libmanda)
+SET(PACKAGE_VERSION 0.1.0)
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+ SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+
+
+# GLIB 2
+pkg_check_modules (GLIB2 REQUIRED glib-2.0)
+SET(GLIB_INCLUDES ${GLIB2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS}/glib-2.0/ ${GLIB2_INCLUDE_DIRS}/glib-2.0/include/)
+INCLUDE_DIRECTORIES(${GLIB_INCLUDES})
+
+SET(MAIN_SOURCE libmanda.c)
+
+SET(PACKAGE_NAME ${CMAKE_PROJECT_NAME})
+SET(PACKAGE_VERSION ${PACKAGE_VERSION})
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libmanda-config.h.cmake ${CMAKE_BINARY_DIR}/libmanda-config.h ESCAPE_QUOTES)
+ADD_DEFINITIONS(-DHAVE_CONFIG_H)
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
+
+add_library(manda SHARED ${MAIN_SOURCE})
+
+ADD_TARGET_PROPERTIES(manda COMPILE_FLAGS "-std=gnu99 -Wall -g -Wshadow -W -pedantic -fPIC -D_GNU_SOURCE")
+
+# GLIB 2
+ADD_TARGET_PROPERTIES(manda LINK_FLAGS "${GLIB2_LDFLAGS}")
+ADD_TARGET_PROPERTIES(manda COMPILE_FLAGS "${GLIB2_CFLAGS_OTHER}")
+
+INSTALL(TARGETS manda DESTINATION lib EXPORT libmanda)
+INSTALL(FILES manda.h ${CMAKE_CURRENT_BINARY_DIR}/libmanda-config.h DESTINATION include)
+INSTALL(EXPORT libmanda DESTINATION lib/libmanda)
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..b6cc1e1
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,22 @@
+
+The MIT License
+
+Copyright (c) 2010 Stefan Bühler
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..5c2d8e6
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,14 @@
+EXTRA_DIST=autogen.sh CMakeLists.txt libmanda-config.h.cmake libmanda.pc.in
+
+ACLOCAL_AMFLAGS=-I m4
+
+AM_CFLAGS=$(GLIB_CFLAGS)
+libmanda_la_LDFLAGS=$(GLIB_LIBS))
+
+lib_LTLIBRARIES=libmanda.la
+libmanda_la_SOURCES=libmanda.c
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = libmanda.pc
+
+$(pkgconfig_DATA): config.status
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..f1f8710
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,54 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.63])
+AC_INIT([libmanda], [0.1.0], [lighttpd@stbuehler.de])
+AC_CONFIG_SRCDIR([libmanda.c])
+AC_CONFIG_HEADERS([libmanda-config.h])
+
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+
+# Checks for programs.
+AC_PROG_CC
+AC_PROG_LIBTOOL
+AC_PROG_MAKE_SET
+
+# Checks for libraries.
+
+# glib-2.0
+PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16.0, [
+ AC_DEFINE([HAVE_GLIB_H], [1], [glib.h])
+],[AC_MSG_ERROR("glib-2.0 >= 2.16.0 not found")])
+
+# Checks for header files.
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h stdlib.h string.h sys/socket.h unistd.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+
+# Checks for library functions.
+AC_FUNC_FORK
+AC_CHECK_FUNCS([dup2])
+
+# check for extra compiler options (warning options)
+if test "${GCC}" = "yes"; then
+ CFLAGS="${CFLAGS} -Wall -W -Wshadow -pedantic -std=gnu99"
+fi
+
+AC_ARG_ENABLE(extra-warnings,
+ AC_HELP_STRING([--enable-extra-warnings],[enable extra warnings (gcc specific)]),
+ [case "${enableval}" in
+ yes) extrawarnings=true ;;
+ no) extrawarnings=false ;;
+ *) AC_MSG_ERROR(bad value ${enableval} for --enable-extra-warnings) ;;
+ esac],[extrawarnings=false])
+
+if test x$extrawarnings = xtrue; then
+ CFLAGS="${CFLAGS} -g -O2 -g2 -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wno-pointer-sign -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wl,--as-needed -Wformat-security"
+fi
+
+AC_CONFIG_FILES([Makefile libmanda.pc])
+AC_OUTPUT
diff --git a/libmanda-config.h.cmake b/libmanda-config.h.cmake
new file mode 100644
index 0000000..6fc5e89
--- /dev/null
+++ b/libmanda-config.h.cmake
@@ -0,0 +1,6 @@
+/*
+ CMake autogenerated config.h file. Do not edit!
+*/
+
+#define LIBMANDA_PACKAGE_NAME "${PACKAGE_NAME}"
+#define LIBMANDA_PACKAGE_VERSION "${PACKAGE_VERSION}"
diff --git a/libmanda-protocol.h b/libmanda-protocol.h
new file mode 100644
index 0000000..0725019
--- /dev/null
+++ b/libmanda-protocol.h
@@ -0,0 +1,82 @@
+#ifndef _LIBMANDA_LIBMANDA_PROTOCOL_H
+#define _LIBMANDA_LIBMANDA_PROTOCOL_H
+
+/*
+ * The webserver side is considered to be the *client* here,
+ * and the spawn manager the *server*.
+ *
+ * 16-bit | 16-bit
+ * +------------+------------+
+ * | Command | Paket size |
+ * +-------------------------+
+ * | Req ID | ResponseID |
+ * +-------------------------+
+ * | Payload... |
+ * +-------------------------+
+ *
+ * ReqID == 0 if no response is expected
+ * ResponseID != 0: response to the request with that id
+ * Each side maintains its own set of request ids
+ *
+ * A response may use a different command; this depends on the commands.
+ *
+ * A request id can be reused after a response for it was received.
+ * Don't use the same id for different commands at the same time.
+ *
+ * For now, commands are either:
+ * - Requests: they have ReqID != 0 and ResponseID == 0
+ * - Responses: ReqID == 0 and ResponseID == the request id the response is for
+ * - Notifications: ReqID == 0 and ResponseID == 0
+ *
+ * Encoding rules:
+ *
+ * Integers are encoded in network byte order: the word 0xABCD is encoded as 0xAB 0xCD
+ *
+ * Socket adresses are encoded as strings, currently the following formats are defined:
+ * - unix:/path/to/socket
+ * - tcp:127.0.0.1:9000
+ * - tcp:[::1]:9000
+ * - udp:127.0.0.1:9000
+ * - udp:[::1]:9000
+ *
+ * Strings are encoded as | length (unsigned 16-bit) | length * byte |, without terminating '\0'
+ *
+ * Commands:
+ *
+ * - 0x0001: Bind a new backend
+ * Client -> Server (Request):
+ * payload is the "name" string.
+ *
+ * request the socket address for a "new" backend; the name can
+ * basically be anything, it is recommended to use either the
+ * socket address (for example "unix:/var/run/fastcgi_php_www-default.sock")
+ * or a comma separated list of key=value pairs ("type=php5,user=www-default")
+ *
+ * Server -> Client (Response):
+ * payload is a 32-bit backend identifier, followed by the socket address (or an error message)
+ *
+ * A valid backend identifier mustn't be zero, and a valid backend must have a valid socket address.
+ * An error is signaled by a zero identifier, the following string contains an optional error message.
+ *
+ * The server may return the same id more than once for the same backend;
+ * the client must release each id as often as it got it in a bind request.
+ *
+ * - 0x0002: Release backend
+ * Client -> Server (Notification):
+ * payload is the 32-bit backend identifier
+ *
+ * - 0x0003: Update backend
+ * Client -> Server (Notification):
+ * payload are three unsigned 32-bit integers: backend identifier, "load" and "workers"
+ * "load" is the number of requests the client would like to process with the backend right now,
+ * and "workers" is the number of "workers" the client thinks the server should spawn.
+ *
+ * It is up to the server what to make of this information; in most cases it will ignore the "workers"
+ * parameter and calculate the needed workers from the "load" parameter.
+ *
+ * The "workers" parameter may be useful in cases where you cascade different spawn-managers; the
+ * main spawn-manager may tell a sub spawn-manager how many children / threads it should use.
+ *
+ */
+
+#endif
diff --git a/libmanda.c b/libmanda.c
new file mode 100644
index 0000000..cf5436a
--- /dev/null
+++ b/libmanda.c
@@ -0,0 +1,10 @@
+
+#include "libmanda.h"
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
diff --git a/libmanda.h b/libmanda.h
new file mode 100644
index 0000000..69b8431
--- /dev/null
+++ b/libmanda.h
@@ -0,0 +1,125 @@
+#ifndef _LIBMANDA_LIBMANDA_H
+#define _LIBMANDA_LIBMANDA_H
+
+#include "libmanda-config.h"
+
+#include <glib.h>
+
+#include <sys/socket.h>
+
+typedef enum {
+ MANDA_FD_READ = 1,
+ MANDA_FD_WRITE = 2
+} manda_async_events;
+
+typedef struct manda_async_ctrl manda_async_ctrl;
+typedef struct manda_fd_watcher manda_fd_watcher;
+typedef struct manda_timeout manda_timeout;
+
+typedef struct manda_server_callbacks manda_server_callbacks;
+typedef struct manda_server_connection manda_server_connection;
+typedef struct manda_server manda_server;
+
+typedef struct manda_client manda_client;
+
+typedef void (*manda_fd_watcher_cb)(manda_fd_watcher *watcher);
+
+typedef void (*manda_new_fd_watcher)(gpointer srv, manda_fd_watcher *watcher);
+typedef void (*manda_update_fd_watcher)(gpointer srv, manda_fd_watcher *watcher);
+typedef void (*manda_destroy_fd_watcher)(gpointer srv, manda_fd_watcher *watcher);
+
+typedef void (*manda_timeout_cb)(manda_timeout *timeout);
+
+typedef void (*manda_new_timeout)(gpointer srv, manda_timeout *timeout);
+typedef void (*manda_start_timeout)(gpointer srv, manda_timeout *timeout);
+typedef void (*manda_destroy_timeout)(gpointer srv, manda_timeout *timeout);
+
+struct manda_async_ctrl {
+ manda_new_fd_watcher new_fd_watcher;
+ manda_update_fd_watcher update_fd_watcher;
+ manda_destroy_fd_watcher destroy_fd_watcher;
+
+ manda_new_timeout new_timeout;
+ manda_start_timeout start_timeout; /* one shot */
+ manda_destroy_timeout destroy_timeout;
+};
+
+struct manda_fd_watcher {
+ gpointer data; /* application data */
+ manda_fd_watcher_cb callback;
+
+ /* private from here */
+
+ gpointer priv;
+
+ int events; /* bitmask of manda_async_events; "update_fd_watcher" needs to check this */
+ int fd; /* filedescriptor; doesn't get changed after "new_fd_watcher" */
+};
+
+struct manda_timeout {
+ gpointer data; /* application data */
+ manda_timeout_cb callback;
+
+ /* private from here */
+
+ gpointer priv;
+};
+
+/* Server API */
+
+typedef void (*manda_server_new_connection)(gpointer srv, manda_server_connection *con);
+typedef void (*manda_server_closed_connection)(gpointer srv, manda_server_connection *con);
+
+typedef void (*manda_server_acquire_backend)(gpointer srv, manda_server_connection *con, GString *name, guint16 reqid);
+typedef void (*manda_server_update_backend)(gpointer srv, manda_server_connection *con, guint32 load, guint32 backends);
+typedef void (*manda_server_release_backend)(gpointer srv, manda_server_connection *con, guint32 id);
+
+struct manda_server_callbacks {
+ manda_server_new_connection server_new_connection;
+ manda_server_closed_connection server_closed_connection;
+
+ manda_server_acquire_backend server_acquire_backend;
+ manda_server_update_backend server_update_backend;
+ manda_server_release_backend server_release_backend;
+};
+
+struct manda_server_connection {
+ gpointer data; /* application data */
+
+ /* private from here */
+
+ gboolean delete_later;
+};
+
+struct manda_server {
+ gint refcount;
+ gpointer data; /* application data */
+
+ const manda_async_ctrl *ctrl;
+ const manda_server_callbacks *callbacks;
+};
+
+manda_server* manda_server_new(gpointer srv, const manda_async_ctrl *ctrl, const manda_server_callbacks *callbacks);
+void manda_server_acquire(manda_server *s);
+void manda_server_release(manda_server *s);
+
+void manda_server_add_socket(manda_server *s, int fd, gpointer data);
+
+/* Client API */
+
+struct manda_client { /* private */
+ gint refcount;
+ gpointer data; /* application data */
+
+ const manda_async_ctrl *ctrl;
+
+ struct sockaddr *addr;
+ socklen_t addrlen;
+};
+
+manda_client* manda_client_new(gpointer srv, const manda_async_ctrl *ctrl, struct sockaddr *addr, socklen_t addrlen);
+void manda_client_acquire(manda_client *c);
+void manda_client_release(manda_client *c);
+
+
+#endif
diff --git a/libmanda.pc.in b/libmanda.pc.in
new file mode 100644
index 0000000..1bb0068
--- /dev/null
+++ b/libmanda.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libmanda
+Description: asynchronous MANDA library
+Version: @VERSION@
+Requires: glib-2.0
+Libs: -L${libdir} -lmanda
+Cflags: