Browse Source

Initial commit

master
Stefan Bühler 10 years ago
commit
c39c6ee64b
10 changed files with 393 additions and 0 deletions
  1. +13
    -0
      .gitignore
  2. +56
    -0
      CMakeLists.txt
  3. +22
    -0
      COPYING
  4. +14
    -0
      Makefile.am
  5. +54
    -0
      configure.ac
  6. +6
    -0
      libmanda-config.h.cmake
  7. +82
    -0
      libmanda-protocol.h
  8. +10
    -0
      libmanda.c
  9. +125
    -0
      libmanda.h
  10. +11
    -0
      libmanda.pc.in

+ 13
- 0
.gitignore View File

@@ -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
*~

+ 56
- 0
CMakeLists.txt View File

@@ -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)

+ 22
- 0
COPYING View File

@@ -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.

+ 14
- 0
Makefile.am View File

@@ -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

+ 54
- 0
configure.ac View File

@@ -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

+ 6
- 0
libmanda-config.h.cmake View File

@@ -0,0 +1,6 @@
/*
CMake autogenerated config.h file. Do not edit!
*/

#define LIBMANDA_PACKAGE_NAME "${PACKAGE_NAME}"
#define LIBMANDA_PACKAGE_VERSION "${PACKAGE_VERSION}"

+ 82
- 0
libmanda-protocol.h View File

@@ -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

+ 10
- 0
libmanda.c View File

@@ -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>


+ 125
- 0
libmanda.h View File

@@ -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

+ 11
- 0
libmanda.pc.in View File

@@ -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:

Loading…
Cancel
Save