Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4837948
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
34 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/docs/html.dox.in b/docs/html.dox.in
index ee418a2..dbad148 100644
--- a/docs/html.dox.in
+++ b/docs/html.dox.in
@@ -1,214 +1,214 @@
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = libqb
PROJECT_NUMBER = @VERSION@
OUTPUT_DIRECTORY = .
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF = YES
ALWAYS_DETAILED_SEC = YES
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 8
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = YES
OPTIMIZE_OUTPUT_JAVA = NO
OPTIMIZE_FOR_FORTRAN = NO
OPTIMIZE_OUTPUT_VHDL = NO
EXTENSION_MAPPING =
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
SIP_SUPPORT = NO
IDL_PROPERTY_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = YES
SUBGROUPING = NO
TYPEDEF_HIDES_STRUCT = YES
SYMBOL_CACHE_SIZE = 0
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = YES
EXTRACT_LOCAL_CLASSES = NO
EXTRACT_LOCAL_METHODS = YES
EXTRACT_ANON_NSPACES = YES
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_CLASSES = YES
HIDE_FRIEND_COMPOUNDS = YES
HIDE_IN_BODY_DOCS = YES
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = NO
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_MEMBERS_CTORS_1ST = NO
SORT_GROUP_NAMES = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = NO
SHOW_FILES = YES
SHOW_NAMESPACES = YES
FILE_VERSION_FILTER =
LAYOUT_FILE =
#---------------------------------------------------------------------------
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT =
WARN_LOGFILE =
#---------------------------------------------------------------------------
INPUT = @srcdir@/../include/qb/ @srcdir@/../docs/
INPUT_ENCODING = UTF-8
FILE_PATTERNS = *.h
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
-EXAMPLE_PATH =
-EXAMPLE_PATTERNS =
+EXAMPLE_PATH = @srcdir@/../examples
+EXAMPLE_PATTERNS = *.c
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER =
FILTER_PATTERNS =
FILTER_SOURCE_FILES = NO
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = NO
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_TIMESTAMP = NO
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
HTML_DYNAMIC_SECTIONS = NO
GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
DOCSET_BUNDLE_ID = org.doxygen.Project
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
CHM_INDEX_ENCODING =
BINARY_TOC = NO
TOC_EXPAND = YES
GENERATE_QHP = NO
QCH_FILE =
QHP_NAMESPACE =
QHP_VIRTUAL_FOLDER = doc
QHP_CUST_FILTER_NAME =
QHP_CUST_FILTER_ATTRS =
QHP_SECT_FILTER_ATTRS =
QHG_LOCATION =
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = NO
USE_INLINE_TREES = NO
TREEVIEW_WIDTH = 250
FORMULA_FONTSIZE = 10
SEARCHENGINE = YES
GENERATE_LATEX = YES
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
LATEX_SOURCE_CODE = NO
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = .
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_XML = NO
GENERATE_AUTOGEN_DEF = NO
GENERATE_PERLMOD = NO
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = NO
SEARCH_INCLUDES = YES
INCLUDE_PATH = @srcdir@/../include
INCLUDE_FILE_PATTERNS = *.h
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
#
#
TAGFILES =
GENERATE_TAGFILE =
ALLEXTERNALS = NO
EXTERNAL_GROUPS = NO
PERL_PATH =
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH =
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = YES
DOT_FONTNAME = FreeSans
DOT_FONTSIZE = 10
DOT_FONTPATH =
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = YES
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
diff --git a/examples/.gitignore b/examples/.gitignore
index 861a32c..bf73ae4 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -1,3 +1,5 @@
simplelog
tcpclient
tcpserver
+ipcclient
+ipcserver
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 867f9d8..f7dee65 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,37 +1,47 @@
# Copyright (c) 2011 Red Hat, Inc.
#
# Authors: Angus Salkeld <asalkeld@redhat.com>
#
# This file is part of libqb.
#
# libqb is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 2.1 of the License, or
# (at your option) any later version.
#
# libqb is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with libqb. If not, see <http://www.gnu.org/licenses/>.
#
MAINTAINERCLEANFILES = Makefiles.in
EXTRA_DIST =
CLEANFILES =
-noinst_PROGRAMS = simplelog tcpclient tcpserver
+noinst_PROGRAMS = simplelog tcpclient tcpserver ipcclient ipcserver
simplelog_SOURCES = simplelog.c $(top_builddir)/include/qb/qblog.h
simplelog_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
simplelog_LDADD = -lrt $(top_builddir)/lib/libqb.la
tcpclient_SOURCES = tcpclient.c $(top_builddir)/include/qb/qbloop.h
tcpclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
tcpclient_LDADD = -lrt $(top_builddir)/lib/libqb.la
tcpserver_SOURCES = tcpserver.c $(top_builddir)/include/qb/qbloop.h
tcpserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
tcpserver_LDADD = -lrt $(top_builddir)/lib/libqb.la
+ipcclient_SOURCES = ipcclient.c $(top_builddir)/include/qb/qbloop.h \
+ $(top_builddir)/include/qb/qbipcc.h
+ipcclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include
+ipcclient_LDADD = -lrt $(top_builddir)/lib/libqb.la
+
+ipcserver_SOURCES = ipcserver.c $(top_builddir)/include/qb/qbloop.h \
+ $(top_builddir)/include/qb/qbipcs.h
+ipcserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ $(GLIB_CFLAGS)
+ipcserver_LDADD = -lrt $(top_builddir)/lib/libqb.la $(GLIB_LIBS)
diff --git a/examples/ipcclient.c b/examples/ipcclient.c
new file mode 100644
index 0000000..c43998f
--- /dev/null
+++ b/examples/ipcclient.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * libqb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * libqb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libqb. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "os_base.h"
+#include <signal.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbutil.h>
+#include <qb/qbipcc.h>
+
+#define MAX_MSG_SIZE (8192)
+
+int
+main(int argc, char *argv[])
+{
+ qb_ipcc_connection_t *conn;
+ int32_t res;
+ char *buffer[MAX_MSG_SIZE];
+
+ conn = qb_ipcc_connect("ipcserver", MAX_MSG_SIZE);
+ if (conn == NULL) {
+ perror("qb_ipcc_connect");
+ exit(1);
+ }
+
+ while(1) {
+ struct qb_ipc_request_header *req_header = (struct qb_ipc_request_header *)buffer;
+ struct qb_ipc_response_header *res_header = (struct qb_ipc_response_header *)buffer;
+ char *data = (char*)buffer + sizeof(struct qb_ipc_request_header);
+
+ printf("SEND (q or Q to quit) : ");
+ if (gets(data) == NULL) {
+ continue;
+ }
+
+ if (strcmp(data , "q") != 0 &&
+ strcmp(data , "Q") != 0) {
+ req_header->id = QB_IPC_MSG_USER_START + 3;
+ req_header->size = sizeof(struct qb_ipc_request_header) + strlen(data) + 1;
+ res = qb_ipcc_send(conn, req_header, req_header->size);
+ if (res < 0) {
+ perror("qb_ipcc_send");
+ }
+ } else {
+ break;
+ }
+
+ if (res > 0) {
+ res = qb_ipcc_recv(conn,
+ buffer,
+ MAX_MSG_SIZE, -1);
+ if (res < 0) {
+ perror("qb_ipcc_recv");
+ }
+ res_header = (struct qb_ipc_response_header*)buffer;
+ data = (char*)buffer + sizeof(struct qb_ipc_response_header);
+ data[res - sizeof(struct qb_ipc_response_header)] = '\0';
+
+ printf("Response[%d]: %s \n", res_header->id, data);
+ }
+ }
+
+ qb_ipcc_disconnect(conn);
+ return EXIT_SUCCESS;
+}
+
diff --git a/examples/ipcserver.c b/examples/ipcserver.c
new file mode 100644
index 0000000..f4c47d4
--- /dev/null
+++ b/examples/ipcserver.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2011 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld@redhat.com>
+ *
+ * libqb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * libqb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libqb. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "os_base.h"
+#include <signal.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbutil.h>
+#include <qb/qblog.h>
+#include <qb/qbloop.h>
+#include <qb/qbipcs.h>
+
+#ifdef HAVE_GLIB
+#include <glib.h>
+static GMainLoop *glib_loop;
+static qb_array_t *gio_map;
+#endif /* HAVE_GLIB */
+
+static int32_t use_glib = QB_FALSE;
+static qb_loop_t *bms_loop;
+static qb_ipcs_service_t* s1;
+
+static int32_t
+s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid)
+{
+#if 0
+ if (uid == 0 && gid == 0) {
+ qb_log(LOG_INFO, "Authenticated connection");
+ return 1;
+ }
+ qb_log(LOG_NOTICE, "BAD user!");
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+static void
+s1_connection_created_fn(qb_ipcs_connection_t *c)
+{
+ struct qb_ipcs_stats srv_stats;
+
+ qb_ipcs_stats_get(s1, &srv_stats, QB_FALSE);
+ qb_log(LOG_INFO, "Connection created (active:%d, closed:%d)",
+ srv_stats.active_connections,
+ srv_stats.closed_connections);
+}
+
+static void
+s1_connection_destroyed_fn(qb_ipcs_connection_t *c)
+{
+ qb_log(LOG_INFO, "Connection about to be freed");
+}
+
+static int32_t
+s1_connection_closed_fn(qb_ipcs_connection_t *c)
+{
+ struct qb_ipcs_connection_stats stats;
+ struct qb_ipcs_stats srv_stats;
+
+ qb_ipcs_stats_get(s1, &srv_stats, QB_FALSE);
+ qb_ipcs_connection_stats_get(c, &stats, QB_FALSE);
+ qb_log(LOG_INFO, "Connection to pid:%d destroyed (active:%d, closed:%d)",
+ stats.client_pid,
+ srv_stats.active_connections,
+ srv_stats.closed_connections);
+
+ qb_log(LOG_DEBUG, " Requests %"PRIu64"", stats.requests);
+ qb_log(LOG_DEBUG, " Responses %"PRIu64"", stats.responses);
+ qb_log(LOG_DEBUG, " Events %"PRIu64"", stats.events);
+ qb_log(LOG_DEBUG, " Send retries %"PRIu64"", stats.send_retries);
+ qb_log(LOG_DEBUG, " Recv retries %"PRIu64"", stats.recv_retries);
+ qb_log(LOG_DEBUG, " FC state %d", stats.flow_control_state);
+ qb_log(LOG_DEBUG, " FC count %"PRIu64"", stats.flow_control_count);
+ return 0;
+}
+
+static int32_t
+s1_msg_process_fn(qb_ipcs_connection_t *c,
+ void *data, size_t size)
+{
+ struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data;
+ struct qb_ipc_response_header response;
+ ssize_t res;
+ struct iovec iov[2];
+ char resp[100];
+
+ qb_log(LOG_DEBUG, "msg received (id:%d, size:%d)",
+ req_pt->id, req_pt->size);
+ response.size = sizeof(struct qb_ipc_response_header);
+ response.id = 13;
+ response.error = 0;
+
+ snprintf(resp, 100, "ACK %zd bytes", size);
+ iov[0].iov_len = sizeof(response);
+ iov[0].iov_base = &response;
+ iov[1].iov_len = strlen(resp);
+ iov[1].iov_base = resp;
+
+ res = qb_ipcs_response_sendv(c, iov, 2);
+ if (res < 0) {
+ qb_perror(LOG_ERR, "qb_ipcs_response_send");
+ }
+ return 0;
+}
+
+static void
+sigusr1_handler(int32_t num)
+{
+ qb_log(LOG_DEBUG, "(%d)", num);
+ qb_ipcs_destroy(s1);
+ exit(0);
+}
+
+static void
+show_usage(const char *name)
+{
+ printf("usage: \n");
+ printf("%s <options>\n", name);
+ printf("\n");
+ printf(" options:\n");
+ printf("\n");
+ printf(" -h show this help text\n");
+ printf(" -m use shared memory\n");
+ printf(" -p use posix message queues\n");
+ printf(" -s use sysv message queues\n");
+ printf(" -u use unix sockets\n");
+ printf(" -g use glib mainloop\n");
+ printf("\n");
+}
+
+#ifdef HAVE_GLIB
+struct gio_to_qb_poll {
+ int32_t is_used;
+ GIOChannel *channel;
+ int32_t events;
+ void * data;
+ qb_ipcs_dispatch_fn_t fn;
+ enum qb_loop_priority p;
+};
+
+static gboolean
+gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data)
+{
+ struct gio_to_qb_poll *adaptor = (struct gio_to_qb_poll *)data;
+ gint fd = g_io_channel_unix_get_fd(gio);
+
+ return (adaptor->fn(fd, condition, adaptor->data) == 0);
+}
+
+static int32_t
+my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
+ void *data, qb_ipcs_dispatch_fn_t fn)
+{
+ struct gio_to_qb_poll *adaptor;
+ GIOChannel *channel;
+ int32_t res = 0;
+
+ res = qb_array_grow(gio_map, fd + 1);
+ if (res < 0) {
+ return res;
+ }
+ res = qb_array_index(gio_map, fd, (void**)&adaptor);
+ if (res < 0) {
+ return res;
+ }
+ if (adaptor->is_used) {
+ return -EEXIST;
+ }
+
+ channel = g_io_channel_unix_new(fd);
+ if (!channel) {
+ return -ENOMEM;
+ }
+
+ adaptor->channel = channel;
+ adaptor->fn = fn;
+ adaptor->events = evts;
+ adaptor->data = data;
+ adaptor->p = p;
+ adaptor->is_used = QB_TRUE;
+
+ g_io_add_watch(channel, evts, gio_read_socket, adaptor);
+ return 0;
+}
+
+static int32_t
+my_g_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t evts,
+ void *data, qb_ipcs_dispatch_fn_t fn)
+{
+ return 0;
+}
+
+static int32_t
+my_g_dispatch_del(int32_t fd)
+{
+ struct gio_to_qb_poll *adaptor;
+ if (qb_array_index(gio_map, fd, (void**)&adaptor) == 0) {
+ g_io_channel_unref(adaptor->channel);
+ adaptor->is_used = QB_FALSE;
+ }
+ return 0;
+}
+#endif /* HAVE_GLIB */
+
+static int32_t
+my_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn)
+{
+ return qb_loop_job_add(bms_loop, p, data, fn);
+}
+
+static int32_t
+my_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
+ void *data, qb_ipcs_dispatch_fn_t fn)
+{
+ return qb_loop_poll_add(bms_loop, p, fd, evts, data, fn);
+}
+
+static int32_t
+my_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t evts,
+ void *data, qb_ipcs_dispatch_fn_t fn)
+{
+ return qb_loop_poll_mod(bms_loop, p, fd, evts, data, fn);
+}
+
+static int32_t
+my_dispatch_del(int32_t fd)
+{
+ return qb_loop_poll_del(bms_loop, fd);
+}
+
+int32_t
+main(int32_t argc, char *argv[])
+{
+ const char *options = "mpsugh";
+ int32_t opt;
+ enum qb_ipc_type ipc_type = QB_IPC_SHM;
+ struct qb_ipcs_service_handlers sh = {
+ .connection_accept = s1_connection_accept_fn,
+ .connection_created = s1_connection_created_fn,
+ .msg_process = s1_msg_process_fn,
+ .connection_destroyed = s1_connection_destroyed_fn,
+ .connection_closed = s1_connection_closed_fn,
+ };
+ struct qb_ipcs_poll_handlers ph = {
+ .job_add = my_job_add,
+ .dispatch_add = my_dispatch_add,
+ .dispatch_mod = my_dispatch_mod,
+ .dispatch_del = my_dispatch_del,
+ };
+#ifdef HAVE_GLIB
+ struct qb_ipcs_poll_handlers glib_ph = {
+ .job_add = NULL, /* FIXME */
+ .dispatch_add = my_g_dispatch_add,
+ .dispatch_mod = my_g_dispatch_mod,
+ .dispatch_del = my_g_dispatch_del,
+ };
+#endif /* HAVE_GLIB */
+
+ while ((opt = getopt(argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'm':
+ ipc_type = QB_IPC_SHM;
+ break;
+ case 's':
+ ipc_type = QB_IPC_SYSV_MQ;
+ break;
+ case 'u':
+ ipc_type = QB_IPC_SOCKET;
+ break;
+ case 'p':
+ ipc_type = QB_IPC_POSIX_MQ;
+ break;
+ case 'g':
+ use_glib = QB_TRUE;
+ break;
+ case 'h':
+ default:
+ show_usage(argv[0]);
+ exit(0);
+ break;
+ }
+ }
+ signal(SIGINT, sigusr1_handler);
+
+ qb_log_init("ipcserver", LOG_USER, LOG_WARNING);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, __FILE__,
+ LOG_DEBUG);
+ qb_log_format_set(QB_LOG_STDERR, "%f:%l [%p] %b");
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+
+ s1 = qb_ipcs_create("ipcserver", 0, ipc_type, &sh);
+ if (s1 == 0) {
+ qb_perror(LOG_ERR, "qb_ipcs_create");
+ exit(1);
+ }
+ if (!use_glib) {
+ bms_loop = qb_loop_create();
+ qb_ipcs_poll_handlers_set(s1, &ph);
+ qb_ipcs_run(s1);
+ qb_loop_run(bms_loop);
+ } else {
+#ifdef HAVE_GLIB
+ glib_loop = g_main_loop_new(NULL, FALSE);
+ gio_map = qb_array_create(64, sizeof(struct gio_to_qb_poll));
+ qb_ipcs_poll_handlers_set(s1, &glib_ph);
+ qb_ipcs_run(s1);
+ g_main_loop_run(glib_loop);
+#else
+ qb_log(LOG_ERR, "You don't seem to have glib-devel installed.\n");
+#endif
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h
index 2b978fc..0d71293 100644
--- a/include/qb/qbipcc.h
+++ b/include/qb/qbipcc.h
@@ -1,156 +1,159 @@
/*
* Copyright (C) 2006-2007, 2009 Red Hat, Inc.
*
* Author: Steven Dake <sdake@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QB_IPCC_H_DEFINED
#define QB_IPCC_H_DEFINED
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#include <pthread.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <qb/qbhdb.h>
#include <qb/qbipc_common.h>
/**
* @file qbipcc.h
*
* Client IPC API.
*
* @par Lifecycle of an IPC connection.
* An IPC connection is made to the server with qb_ipcc_connect(). This function
* connects to the server and requests channels be created for communication.
* To disconnect, the client either exits or executes the function qb_ipcc_disconnect().
*
* @par Synchronous communication
* The function qb_ipcc_sendv_recv() sends an iovector request and receives a response.
*
* @par Asynchronous requests from the client
* The function qb_ipcc_sendv() sends an iovector request.
* The function qb_ipcc_send() sends an message buffer request.
*
* @par Asynchronous events from the server
* The qb_ipcc_event_recv() function receives an out-of-band asyncronous message.
* The asynchronous messages are queued and can provide very high out-of-band performance.
* To determine when to call qb_ipcc_event_recv() the qb_ipcc_fd_get() call is
* used to obtain a file descriptor used in the poll() or select() system calls.
+ *
+ * @example ipcclient.c
+ * This is an example of how to use the client.
*/
typedef struct qb_ipcc_connection qb_ipcc_connection_t;
/**
* Create a connection to an IPC service.
*
* @param name name of the service.
* @param max_msg_size biggest msg size.
* @return NULL (error: see errno) or a connection object.
*/
qb_ipcc_connection_t*
qb_ipcc_connect(const char *name, size_t max_msg_size);
/**
* Disconnect an IPC connection.
*
* @param c connection instance
*/
void qb_ipcc_disconnect(qb_ipcc_connection_t* c);
/**
* Get the file descriptor to poll.
*
* @param c connection instance
* @param fd (out) file descriptor to poll
*/
int32_t qb_ipcc_fd_get(qb_ipcc_connection_t* c, int32_t * fd);
/**
* Send a message.
*
* @param c connection instance
* @param msg_ptr pointer to a message to send
* @param msg_len the size of the message
* @return (size sent, -errno == error)
*/
ssize_t qb_ipcc_send(qb_ipcc_connection_t* c, const void *msg_ptr,
size_t msg_len);
/**
* Send a message (iovec).
*
* @param c connection instance
* @param iov pointer to an iovec struct to send
* @param iov_len the number of iovecs used
* @return (size sent, -errno == error)
*/
ssize_t qb_ipcc_sendv(qb_ipcc_connection_t* c, const struct iovec* iov,
size_t iov_len);
/**
* Receive a response.
*
* @param c connection instance
* @param msg_ptr pointer to a message buffer to receive into
* @param msg_len the size of the buffer
* @param ms_timeout max time to wait for a response
* @return (size recv'ed, -errno == error)
*/
ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr,
size_t msg_len, int32_t ms_timeout);
/**
* This is a convenience function that simply sends and then recvs.
*
* @param c connection instance
* @param iov pointer to an iovec struct to send
* @param iov_len the number of iovecs used
* @param msg_ptr pointer to a message buffer to receive into
* @param msg_len the size of the buffer
* @param ms_timeout max time to wait for a response
*
* @see qb_ipcc_sendv() qb_ipcc_recv()
*/
ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c,
const struct iovec *iov, uint32_t iov_len,
void *msg_ptr, size_t msg_len,
int32_t ms_timeout);
/**
* Receive an event.
*
* @param c connection instance
* @param msg_ptr pointer to a message buffer to receive into
* @param msg_len the size of the buffer
* @param ms_timeout time in milli seconds to wait for a message
* 0 == no wait, negative == block, positive == wait X ms.
* @param ms_timeout max time to wait for a response
* @return size of the message or error (-errno)
*/
ssize_t qb_ipcc_event_recv(qb_ipcc_connection_t* c, void *msg_ptr,
size_t msg_len, int32_t ms_timeout);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* QB_IPCC_H_DEFINED */
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h
index 8d02373..eef90d2 100644
--- a/include/qb/qbipcs.h
+++ b/include/qb/qbipcs.h
@@ -1,332 +1,340 @@
/*
* Copyright (C) 2006-2009 Red Hat, Inc.
*
* Author: Steven Dake <sdake@redhat.com>,
* Angus Salkeld <asalkeld@redhat.com>
*
* This file is part of libqb.
*
* libqb is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* libqb is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QB_IPCS_H_DEFINED
#define QB_IPCS_H_DEFINED
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#include <stdlib.h>
#include <qb/qbipc_common.h>
#include <qb/qbhdb.h>
#include <qb/qbloop.h>
+/**
+ * @file qbipcs.h
+ *
+ * Server IPC API.
+ *
+ * @example ipcserver.c
+ */
+
enum qb_ipcs_rate_limit {
QB_IPCS_RATE_FAST,
QB_IPCS_RATE_NORMAL,
QB_IPCS_RATE_SLOW,
QB_IPCS_RATE_OFF,
};
struct qb_ipcs_connection;
typedef struct qb_ipcs_connection qb_ipcs_connection_t;
struct qb_ipcs_service;
typedef struct qb_ipcs_service qb_ipcs_service_t;
struct qb_ipcs_stats {
uint32_t active_connections;
uint32_t closed_connections;
};
struct qb_ipcs_connection_stats {
int32_t client_pid;
uint64_t requests;
uint64_t responses;
uint64_t events;
uint64_t send_retries;
uint64_t recv_retries;
int32_t flow_control_state;
uint64_t flow_control_count;
};
typedef int32_t (*qb_ipcs_dispatch_fn_t) (int32_t fd, int32_t revents,
void *data);
typedef int32_t (*qb_ipcs_dispatch_add_fn)(enum qb_loop_priority p,
int32_t fd,
int32_t events,
void *data,
qb_ipcs_dispatch_fn_t fn);
typedef int32_t (*qb_ipcs_dispatch_mod_fn)(enum qb_loop_priority p,
int32_t fd,
int32_t events,
void *data,
qb_ipcs_dispatch_fn_t fn);
typedef int32_t (*qb_ipcs_dispatch_del_fn)(int32_t fd);
typedef int32_t (*qb_ipcs_job_add_fn)(enum qb_loop_priority p,
void *data,
qb_loop_job_dispatch_fn dispatch_fn);
struct qb_ipcs_poll_handlers {
qb_ipcs_job_add_fn job_add;
qb_ipcs_dispatch_add_fn dispatch_add;
qb_ipcs_dispatch_mod_fn dispatch_mod;
qb_ipcs_dispatch_del_fn dispatch_del;
};
/**
* This callback is to check wether you want to accept a new connection.
*
* The type of checks you should do are authentication, service availabilty
* or process resource constraints.
* @return 0 to accept or -errno to indicate a failure (sent back to the client)
*/
typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c, uid_t uid, gid_t gid);
/**
* This is called after a new connection has been created.
*/
typedef void (*qb_ipcs_connection_created_fn) (qb_ipcs_connection_t *c);
/**
* This is called after a connection has been disconnected.
*
* @note if you return anything but 0 this function will be
* repeativily called (until 0 is returned).
*/
typedef int32_t (*qb_ipcs_connection_closed_fn) (qb_ipcs_connection_t *c);
/**
* This is called just before a connection is freed.
*/
typedef void (*qb_ipcs_connection_destroyed_fn) (qb_ipcs_connection_t *c);
/**
* This is the message processing calback.
* It is called with the message data.
*/
typedef int32_t (*qb_ipcs_msg_process_fn) (qb_ipcs_connection_t *c,
void *data, size_t size);
struct qb_ipcs_service_handlers {
qb_ipcs_connection_accept_fn connection_accept;
qb_ipcs_connection_created_fn connection_created;
qb_ipcs_msg_process_fn msg_process;
qb_ipcs_connection_closed_fn connection_closed;
qb_ipcs_connection_destroyed_fn connection_destroyed;
};
/**
* Create a new IPC server.
*
* @param name for clients to connect to.
* @param service_id an integer to associate with the service
* @param type transport type.
* @param handlers callbacks.
* @return the new service instance.
*/
qb_ipcs_service_t* qb_ipcs_create(const char *name,
int32_t service_id,
enum qb_ipc_type type,
struct qb_ipcs_service_handlers *handlers);
/**
* Increase the reference counter on the service object.
*
* @param s service instance
*/
void qb_ipcs_ref(qb_ipcs_service_t *s);
/**
* Decrease the reference counter on the service object.
*
* @param s service instance
*/
void qb_ipcs_unref(qb_ipcs_service_t *s);
/**
* Set your poll callbacks.
*
* @param s service instance
* @param handlers the handlers that you want ipcs to use.
*/
void qb_ipcs_poll_handlers_set(qb_ipcs_service_t* s,
struct qb_ipcs_poll_handlers *handlers);
/**
* run the new IPC server.
* @param s service instance
* @return 0 == ok; -errno to indicate a failure
*/
int32_t qb_ipcs_run(qb_ipcs_service_t* s);
/**
* Destroy the IPC server.
*
* @param s service instance to destroy
*/
void qb_ipcs_destroy(qb_ipcs_service_t* s);
/**
* Limit the incomming request rate.
* @param s service instance
* @param rl the new rate
*/
void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s, enum qb_ipcs_rate_limit rl);
/**
* Send a response to a incomming request.
*
* @param c connection instance
* @param data the message to send
* @param size the size of the message
* @return size sent or -errno for errors
*/
ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data, size_t size);
/**
* Send a response to a incomming request.
*
* @param c connection instance
* @param iov the iovec struct that points to the message to send
* @param iov_len the number of iovecs.
* @return size sent or -errno for errors
*/
ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, size_t iov_len);
/**
* Send an asyncronous event message to the client.
*
* @param c connection instance
* @param data the message to send
* @param size the size of the message
* @return size sent or -errno for errors
*/
ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data, size_t size);
/**
* Send an asyncronous event message to the client.
*
* @param c connection instance
* @param iov the iovec struct that points to the message to send
* @param iov_len the number of iovecs.
* @return size sent or -errno for errors
*/
ssize_t qb_ipcs_event_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, size_t iov_len);
/**
* Increment the connection's reference counter.
*
* @param c connection instance
*/
void qb_ipcs_connection_ref(qb_ipcs_connection_t *c);
/**
* Decrement the connection's reference counter.
*
* @param c connection instance
*/
void qb_ipcs_connection_unref(qb_ipcs_connection_t *c);
/**
* Disconnect from this client.
*
* @param c connection instance
*/
void qb_ipcs_disconnect(qb_ipcs_connection_t *c);
/**
* Get the service id related to this connection's service.
* (as passed into qb_ipcs_create()
*
* @return service id.
*/
int32_t qb_ipcs_service_id_get(qb_ipcs_connection_t *c);
/**
* Associate a "user" pointer with this connection.
*
* @param context the point to associate with this connection.
* @param c connection instance
* @see qb_ipcs_context_get()
*/
void qb_ipcs_context_set(qb_ipcs_connection_t *c, void *context);
/**
* Get the context (set previously)
*
* @param c connection instance
* @return the context
* @see qb_ipcs_context_set()
*/
void *qb_ipcs_context_get(qb_ipcs_connection_t *c);
/**
* Get the connection statistics.
*
* @param stats (out) the statistics structure
* @param clear_after_read clear stats after copying them into stats
* @param c connection instance
* @return 0 == ok; -errno to indicate a failure
*/
int32_t qb_ipcs_connection_stats_get(qb_ipcs_connection_t *c,
struct qb_ipcs_connection_stats* stats,
int32_t clear_after_read);
/**
* Get the service statistics.
*
* @param stats (out) the statistics structure
* @param clear_after_read clear stats after copying them into stats
* @param pt service instance
* @return 0 == ok; -errno to indicate a failure
*/
int32_t qb_ipcs_stats_get(qb_ipcs_service_t* pt,
struct qb_ipcs_stats* stats,
int32_t clear_after_read);
/**
* Get the first connection.
*
* @note call qb_ipcs_connection_ref_dec() after using the connection.
*
* @param pt service instance
* @return first connection
*/
qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_t* pt);
/**
* Get the next connection.
*
* @note call qb_ipcs_connection_ref_dec() after using the connection.
*
* @param pt service instance
* @param current current connection
* @return next connection
*/
qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_t* pt,
qb_ipcs_connection_t *current);
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
#endif /* QB_IPCS_H_DEFINED */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Jul 21, 3:03 AM (4 h, 23 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2082981
Default Alt Text
(34 KB)
Attached To
Mode
rQ LibQB
Attached
Detach File
Event Timeline
Log In to Comment