summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Sustrik <sustrik@250bpm.com>2012-02-22 06:07:15 +0100
committerMartin Sustrik <sustrik@250bpm.com>2012-02-22 06:07:15 +0100
commit8ca02c8a7f6c391a5ac7847eb37c06d1e14ccb7e (patch)
tree6f293167656b70c04591ae09aca4ca32d80dde72
parent3e51110cf71935a1a7dab04c2de43cc0aaf5bc77 (diff)
parenta54c50aca6ec301d7e003334581843203780101b (diff)
Merge branch 'xszmq-for-sustrik' of git.lucina.net:libxs
-rw-r--r--.gitignore4
-rw-r--r--configure.in38
-rw-r--r--include/xszmq.h276
-rw-r--r--include/xszmq_utils.h65
-rw-r--r--include/zmq.h116
-rw-r--r--src/Makefile.am50
-rw-r--r--src/libxszmq.pc.in10
-rw-r--r--src/libzmq.pc.in10
-rw-r--r--src/xszmq.c443
9 files changed, 886 insertions, 126 deletions
diff --git a/.gitignore b/.gitignore
index b1496a5..2d4f5bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,6 +20,8 @@ autom4te.cache
.*
*~
.*~
+include/zmq.h
+include/zmq_utils.h
tests/pair_inproc
tests/pair_ipc
tests/pair_tcp
@@ -53,6 +55,8 @@ doc/*.7
doc/*.html
doc/*.xml
src/libxs.pc
+src/libxszmq.pc
+src/libzmq.pc
bin/
lib/
obj/
diff --git a/configure.in b/configure.in
index 76105c5..45117e6 100644
--- a/configure.in
+++ b/configure.in
@@ -17,15 +17,24 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
# This lets us use PACKAGE_VERSION in Makefiles
AC_SUBST(PACKAGE_VERSION)
-# Libtool -version-info (ABI version)
+# ABI version for libxs (Libtool -version-info)
#
# Don't change this unless you know exactly what you're doing and have read and
# understand:
# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
#
# libxs -version-info current:revision:age
-LTVER="0:0:0"
-AC_SUBST(LTVER)
+LIBXS_ABI_VERSION="0:0:0"
+AC_SUBST(LIBXS_ABI_VERSION)
+
+# ABI version for libxszmq
+#
+# This must be set to the ABI version of libzmq we are emulating.
+# This is currently libzmq 2.1 which is ABI 1.0.0.
+#
+# libxszmq -version-info current:revision:age
+LIBXSZMQ_ABI_VERSION="1:0:0"
+AC_SUBST(LIBXSZMQ_ABI_VERSION)
# Take a copy of original flags
XS_ORIG_CFLAGS="${CFLAGS:-none}"
@@ -268,6 +277,17 @@ AC_HEADER_TIME
AC_TYPE_UINT32_T
AC_C_VOLATILE
+# libzmq compatibility mode
+libxs_libzmq_compat="no"
+AC_ARG_ENABLE([libzmq-compat], [AS_HELP_STRING([--enable-libzmq-compat],
+ [install libzmq compatibility library and headers [default=no]])],
+ [enable_libzmq_compat=$enableval], [enable_libzmq_compat=no])
+
+if test "x$enable_libzmq_compat" != "xno"; then
+ AC_MSG_NOTICE([enabling libzmq compatibility library and headers])
+ libxs_libzmq_compat="yes"
+fi
+
# PGM extension
libxs_pgm_ext="no"
@@ -360,6 +380,7 @@ if test "x$libxs_pedantic" = "xyes"; then
fi
AC_LANG_POP([C++])
+AM_CONDITIONAL(BUILD_LIBZMQ, test "x$libxs_libzmq_compat" = "xyes")
AM_CONDITIONAL(BUILD_PGM, test "x$libxs_pgm_ext" = "xyes")
AM_CONDITIONAL(ON_MINGW, test "x$libxs_on_mingw32" = "xyes")
@@ -379,8 +400,17 @@ AC_SUBST(LIBXS_EXTRA_CXXFLAGS)
AC_SUBST(LIBXS_EXTRA_LDFLAGS)
AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile
- perf/Makefile src/libxs.pc \
+ perf/Makefile src/libxs.pc src/libxszmq.pc \
builds/msvc/Makefile tests/Makefile \
foreign/openpgm/Makefile])
+if test "x$libxs_libzmq_compat" == "xyes"; then
+ AC_CONFIG_FILES([src/libzmq.pc])
+fi
AC_OUTPUT
+if test "x$libxs_libzmq_compat" == "xyes"; then
+ AC_MSG_WARN([The --enable-libzmq-compat option was specified:])
+ AC_MSG_WARN([libzmq compatibility library and headers are enabled.])
+ AC_MSG_WARN([This will overwrite any existing installation of libzmq.])
+fi
+
diff --git a/include/xszmq.h b/include/xszmq.h
new file mode 100644
index 0000000..eabf3c8
--- /dev/null
+++ b/include/xszmq.h
@@ -0,0 +1,276 @@
+/*
+ Copyright (c) 2012 Martin Lucina
+ Copyright (c) 2007-2011 iMatix Corporation
+ Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
+
+ This file is part of Crossroads I/O.
+
+ Crossroads I/O 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 3 of the License, or
+ (at your option) any later version.
+
+ Crossroads I/O 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __XSZMQ_H_INCLUDED__
+#define __XSZMQ_H_INCLUDED__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#if defined _WIN32
+#include <winsock2.h>
+#endif
+
+/* Handle DSO symbol visibility */
+#if defined _WIN32
+# if defined DLL_EXPORT
+# define XSZMQ_EXPORT __declspec(dllexport)
+# else
+# define XSZMQ_EXPORT __declspec(dllimport)
+# endif
+#else
+# if defined __SUNPRO_C || defined __SUNPRO_CC
+# define XSZMQ_EXPORT __global
+# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
+# define XSZMQ_EXPORT __attribute__ ((visibility("default")))
+# else
+# define XSZMQ_EXPORT
+# endif
+#endif
+
+/******************************************************************************/
+/* 0MQ versioning support. */
+/******************************************************************************/
+
+/* Version macros for compile-time API version detection */
+#define ZMQ_VERSION_MAJOR 2
+#define ZMQ_VERSION_MINOR 1
+#define ZMQ_VERSION_PATCH 11
+
+#define ZMQ_MAKE_VERSION(major, minor, patch) \
+ ((major) * 10000 + (minor) * 100 + (patch))
+#define ZMQ_VERSION \
+ ZMQ_MAKE_VERSION(ZMQ_VERSION_MAJOR, ZMQ_VERSION_MINOR, ZMQ_VERSION_PATCH)
+
+/* Run-time API version detection */
+XSZMQ_EXPORT void zmq_version (int *major, int *minor, int *patch);
+
+/******************************************************************************/
+/* 0MQ errors. */
+/******************************************************************************/
+
+/* These constants conflict with xs.h. Disable them if we are building the */
+/* libxszmq compatibility library itself. */
+#ifndef XS_BUILDING_LIBXSZMQ
+
+/* A number random enough not to collide with different errno ranges on */
+/* different OSes. The assumption is that error_t is at least 32-bit type. */
+#define ZMQ_HAUSNUMERO 156384712
+
+/* On Windows platform some of the standard POSIX errnos are not defined. */
+#ifndef ENOTSUP
+#define ENOTSUP (ZMQ_HAUSNUMERO + 1)
+#endif
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT (ZMQ_HAUSNUMERO + 2)
+#endif
+#ifndef ENOBUFS
+#define ENOBUFS (ZMQ_HAUSNUMERO + 3)
+#endif
+#ifndef ENETDOWN
+#define ENETDOWN (ZMQ_HAUSNUMERO + 4)
+#endif
+#ifndef EADDRINUSE
+#define EADDRINUSE (ZMQ_HAUSNUMERO + 5)
+#endif
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL (ZMQ_HAUSNUMERO + 6)
+#endif
+#ifndef ECONNREFUSED
+#define ECONNREFUSED (ZMQ_HAUSNUMERO + 7)
+#endif
+#ifndef EINPROGRESS
+#define EINPROGRESS (ZMQ_HAUSNUMERO + 8)
+#endif
+#ifndef ENOTSOCK
+#define ENOTSOCK (ZMQ_HAUSNUMERO + 9)
+#endif
+
+/* Native 0MQ error codes. */
+#define EFSM (ZMQ_HAUSNUMERO + 51)
+#define ENOCOMPATPROTO (ZMQ_HAUSNUMERO + 52)
+#define ETERM (ZMQ_HAUSNUMERO + 53)
+#define EMTHREAD (ZMQ_HAUSNUMERO + 54)
+
+#endif /* XS_BUILDING_LIBXSZMQ */
+
+/* This function retrieves the errno as it is known to 0MQ library. The goal */
+/* of this function is to make the code 100% portable, including where 0MQ */
+/* compiled with certain CRT library (on Windows) is linked to an */
+/* application that uses different CRT library. */
+XSZMQ_EXPORT int zmq_errno (void);
+
+/* Resolves system errors and 0MQ errors to human-readable string. */
+XSZMQ_EXPORT const char *zmq_strerror (int errnum);
+
+/******************************************************************************/
+/* 0MQ message definition. */
+/******************************************************************************/
+
+/* Maximal size of "Very Small Message". VSMs are passed by value */
+/* to avoid excessive memory allocation/deallocation. */
+/* If VMSs larger than 255 bytes are required, type of 'vsm_size' */
+/* field in zmq_msg_t structure should be modified accordingly. */
+#define ZMQ_MAX_VSM_SIZE 30
+
+/* Message types. These integers may be stored in 'content' member of the */
+/* message instead of regular pointer to the data. */
+#define ZMQ_DELIMITER 31
+#define ZMQ_VSM 32
+
+/* Message flags. ZMQ_MSG_SHARED is strictly speaking not a message flag */
+/* (it has no equivalent in the wire format), however, making it a flag */
+/* allows us to pack the stucture tigher and thus improve performance. */
+#define ZMQ_MSG_MORE 1
+#define ZMQ_MSG_SHARED 128
+#define ZMQ_MSG_MASK 129 /* Merges all the flags */
+
+/* A message. Note that 'content' is not a pointer to the raw data. */
+/* Rather it is pointer to zmq::msg_content_t structure */
+/* (see src/msg_content.hpp for its definition). */
+typedef struct
+{
+ void *content;
+ unsigned char flags;
+ unsigned char vsm_size;
+ unsigned char vsm_data [ZMQ_MAX_VSM_SIZE];
+} zmq_msg_t;
+
+typedef void (zmq_free_fn) (void *data, void *hint);
+
+XSZMQ_EXPORT int zmq_msg_init (zmq_msg_t *msg);
+XSZMQ_EXPORT int zmq_msg_init_size (zmq_msg_t *msg, size_t size);
+XSZMQ_EXPORT int zmq_msg_init_data (zmq_msg_t *msg, void *data,
+ size_t size, zmq_free_fn *ffn, void *hint);
+XSZMQ_EXPORT int zmq_msg_close (zmq_msg_t *msg);
+XSZMQ_EXPORT int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src);
+XSZMQ_EXPORT int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src);
+XSZMQ_EXPORT void *zmq_msg_data (zmq_msg_t *msg);
+XSZMQ_EXPORT size_t zmq_msg_size (zmq_msg_t *msg);
+
+/******************************************************************************/
+/* 0MQ infrastructure (a.k.a. context) initialisation & termination. */
+/******************************************************************************/
+
+XSZMQ_EXPORT void *zmq_init (int io_threads);
+XSZMQ_EXPORT int zmq_term (void *context);
+
+/******************************************************************************/
+/* 0MQ socket definition. */
+/******************************************************************************/
+
+/* Socket types. */
+#define ZMQ_PAIR 0
+#define ZMQ_PUB 1
+#define ZMQ_SUB 2
+#define ZMQ_REQ 3
+#define ZMQ_REP 4
+#define ZMQ_DEALER 5
+#define ZMQ_ROUTER 6
+#define ZMQ_PULL 7
+#define ZMQ_PUSH 8
+#define ZMQ_XPUB 9
+#define ZMQ_XSUB 10
+#define ZMQ_XREQ ZMQ_DEALER /* Old alias, remove in 3.x */
+#define ZMQ_XREP ZMQ_ROUTER /* Old alias, remove in 3.x */
+#define ZMQ_UPSTREAM ZMQ_PULL /* Old alias, remove in 3.x */
+#define ZMQ_DOWNSTREAM ZMQ_PUSH /* Old alias, remove in 3.x */
+
+/* Socket options. */
+#define ZMQ_HWM 1
+#define ZMQ_SWAP 3
+#define ZMQ_AFFINITY 4
+#define ZMQ_IDENTITY 5
+#define ZMQ_SUBSCRIBE 6
+#define ZMQ_UNSUBSCRIBE 7
+#define ZMQ_RATE 8
+#define ZMQ_RECOVERY_IVL 9
+#define ZMQ_MCAST_LOOP 10
+#define ZMQ_SNDBUF 11
+#define ZMQ_RCVBUF 12
+#define ZMQ_RCVMORE 13
+#define ZMQ_FD 14
+#define ZMQ_EVENTS 15
+#define ZMQ_TYPE 16
+#define ZMQ_LINGER 17
+#define ZMQ_RECONNECT_IVL 18
+#define ZMQ_BACKLOG 19
+#define ZMQ_RECOVERY_IVL_MSEC 20 /* opt. recovery time, reconcile in 3.x */
+#define ZMQ_RECONNECT_IVL_MAX 21
+
+/* Send/recv options. */
+#define ZMQ_NOBLOCK 1
+#define ZMQ_SNDMORE 2
+
+XSZMQ_EXPORT void *zmq_socket (void *context, int type);
+XSZMQ_EXPORT int zmq_close (void *s);
+XSZMQ_EXPORT int zmq_setsockopt (void *s, int option, const void *optval,
+ size_t optvallen);
+XSZMQ_EXPORT int zmq_getsockopt (void *s, int option, void *optval,
+ size_t *optvallen);
+XSZMQ_EXPORT int zmq_bind (void *s, const char *addr);
+XSZMQ_EXPORT int zmq_connect (void *s, const char *addr);
+XSZMQ_EXPORT int zmq_send (void *s, zmq_msg_t *msg, int flags);
+XSZMQ_EXPORT int zmq_recv (void *s, zmq_msg_t *msg, int flags);
+
+/******************************************************************************/
+/* I/O multiplexing. */
+/******************************************************************************/
+
+#define ZMQ_POLLIN 1
+#define ZMQ_POLLOUT 2
+#define ZMQ_POLLERR 4
+
+typedef struct
+{
+ void *socket;
+#if defined _WIN32
+ SOCKET fd;
+#else
+ int fd;
+#endif
+ short events;
+ short revents;
+} zmq_pollitem_t;
+
+XSZMQ_EXPORT int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout);
+
+/******************************************************************************/
+/* Built-in devices */
+/******************************************************************************/
+
+#define ZMQ_STREAMER 1
+#define ZMQ_FORWARDER 2
+#define ZMQ_QUEUE 3
+
+XSZMQ_EXPORT int zmq_device (int device, void * insocket, void* outsocket);
+
+#undef XSZMQ_EXPORT
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/include/xszmq_utils.h b/include/xszmq_utils.h
new file mode 100644
index 0000000..b25bf91
--- /dev/null
+++ b/include/xszmq_utils.h
@@ -0,0 +1,65 @@
+/*
+ Copyright (c) 2012 Martin Lucina
+ Copyright (c) 2007-2011 iMatix Corporation
+ Copyright (c) 2007-2011 Other contributors as noted in the AUTHORS file
+
+ This file is part of Crossroads I/O.
+
+ Crossroads I/O 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 3 of the License, or
+ (at your option) any later version.
+
+ Crossroads I/O 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __XSZMQ_UTILS_H_INCLUDED__
+#define __XSZMQ_UTILS_H_INCLUDED__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Handle DSO symbol visibility */
+#if defined _WIN32
+# if defined DLL_EXPORT
+# define XSZMQ_EXPORT __declspec(dllexport)
+# else
+# define XSZMQ_EXPORT __declspec(dllimport)
+# endif
+#else
+# if defined __SUNPRO_C || defined __SUNPRO_CC
+# define XSZMQ_EXPORT __global
+# elif (defined __GNUC__ && __GNUC__ >= 4) || defined __INTEL_COMPILER
+# define XSZMQ_EXPORT __attribute__ ((visibility("default")))
+# else
+# define XSZMQ_EXPORT
+# endif
+#endif
+
+/* Helper functions are used by perf tests so that they don't have to care */
+/* about minutiae of time-related functions on different OS platforms. */
+
+/* Starts the stopwatch. Returns the handle to the watch. */
+XSZMQ_EXPORT void *zmq_stopwatch_start (void);
+
+/* Stops the stopwatch. Returns the number of microseconds elapsed since */
+/* the stopwatch was started. */
+XSZMQ_EXPORT unsigned long zmq_stopwatch_stop (void *watch_);
+
+/* Sleeps for specified number of seconds. */
+XSZMQ_EXPORT void zmq_sleep (int seconds_);
+
+#undef XSZMQ_EXPORT
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/include/zmq.h b/include/zmq.h
deleted file mode 100644
index 11270f9..0000000
--- a/include/zmq.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- Copyright (c) 2012 250bpm s.r.o.
- Copyright (c) 2012 Other contributors as noted in the AUTHORS file
-
- This file is part of Crossroads I/O project.
-
- Crossroads I/O 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 3 of the License, or
- (at your option) any later version.
-
- Crossroads 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 this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __ZMQ_H_INCLUDED__
-#define __ZMQ_H_INCLUDED__
-
-// ZeroMQ compatibility header file.
-
-#include <xs.h>
-
-#define ZMQ_USE_XS
-#define ZMQ_VERSION_MAJOR XS_VERSION_MAJOR
-#define ZMQ_VERSION_MINOR XS_VERSION_MINOR
-#define ZMQVERSION_PATCH XS_VERSION_PATCH
-#define ZMQ_MAKE_VERSION(major, minor, patch) \
- XS_MAKE_VERSION(major, ninor, patch)
-#define ZMQ_VERSION XS_VERSION
-#define zmq_version xs_version
-
-#define zmq_errno xs_errno
-#define zmq_strerror xs_strerror
-
-#define zmq_msg_t xs_msg_t
-#define zmq_free_fd xs_free_fn
-#define zmq_msg_init xs_msg_init
-#define zmq_msg_init_size xs_msg_init_size
-#define zmq_msg_init_data xs_msg_init_data
-#define zmq_msg_close xs_msg_close
-#define zmq_msg_move xs_msg_move
-#define zmq_msg_copy xs_msg_copy
-#define zmq_msg_data xs_msg_data
-#define zmq_msg_size xs_msg_size
-#define zmq_getmsgopt xs_getmsgopt
-
-#define zmq_init xs_init
-#define zmq_term xs_term
-
-#define ZMQ_PAIR XS_PAIR
-#define ZMQ_PUB XS_PUB
-#define ZMQ_SUB XS_SUB
-#define ZMQ_REQ XS_REQ
-#define ZMQ_REP XS_REP
-#define ZMQ_XREQ XS_XREQ
-#define ZMQ_XRER XS_XREP
-#define ZMQ_PULL XS_PULL
-#define ZMQ_PUSH XS_PUSH
-#define ZMQ_XPUB XS_XPUB
-#define ZMQ_XSUB XS_XSUB
-#define ZMQ_ROUTER XS_ROUTER
-#define ZMQ_DEALER XS_DEALER
-
-#define ZMQ_AFFINITY XS_AFFINITY
-#define ZMQ_IDENTITY XS_IDENTITY
-#define ZMQ_SUBSCRIBE XS_SUBSCRIBE
-#define ZMQ_UNSUBSCRIBE XS_UNSUBSCRIBE
-#define ZMQ_RATE XS_RATE
-#define ZMQ_RECOVERY_IVL XS_RECOVERY_IVL
-#define ZMQ_SNDBUF XS_SNDBUF
-#define ZMQ_RCVBUF XS_RCVBUF
-#define ZMQ_RCVMORE XS_RCVMORE
-#define ZMQ_FD XS_FD
-#define ZMQ_EVENTS XS_EVENTS
-#define ZMQ_TYPE XS_TYPE
-#define ZMQ_LINGER XS_LINGER
-#define ZMQ_RCONNECT_IVL XS_RECONNECT_IVL
-#define ZMQ_BACKLOG XS_BACKLOG
-#define ZMQ_RECONNECT_IVL_MAX XS_RECONNECT_IVL_MAX
-#define ZMQ_MAXMSGSIZE XS_MAXMSGSIZE
-#define ZMQ_SNDHWM XS_SNDHWM
-#define ZMQ_RCVHWM XS_RCVHWM
-#define ZMQ_MULTICAST_HOPS XS_MULTICAST_HOPS
-#define ZMQ_RCVTIMEO XS_RCVTIMEO
-#define ZMQ_SNDTIMEO XS_SNDTIMEO
-#define ZMQ_IPV4ONLY XS_IPV4ONLY
-
-#define ZMQ_MORE XS_MORE
-#define ZMQ_DONTWAIT XS_DONTWAIT
-#define ZMQ_SNDMORE XS_SNDMORE
-
-#define zmq_socket xs_socket
-#define zmq_close xs_close
-#define zmq_setsockopt xs_setsockopt
-#define zmq_getsockopt xs_getsockopt
-#define zmq_bind xs_bind
-#define zmq_connect xs_connect
-#define zmq_send xs_send
-#define zmq_recv xs_recv
-#define zmq_sendmsg xs_sendmsg
-#define zmq_recvmsg xs_recvmsg
-
-#define ZMQ_POLLIN XS_POLLIN
-#define ZMQ_POLLOUT XS_POLLOUT
-#define ZMQ_POLLERR XS_POLLERR
-
-#define zmq_pollitem_t xs_pollitem_t
-#define zmq_poll xs_poll
-
-#endif
-
diff --git a/src/Makefile.am b/src/Makefile.am
index 9f11611..3439f4b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,9 +1,30 @@
-lib_LTLIBRARIES = libxs.la
-
pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = libxs.pc
-include_HEADERS = ../include/xs.h ../include/xs_utils.h ../include/zmq.h
+if BUILD_LIBZMQ
+lib_LTLIBRARIES = libxs.la libxszmq.la libzmq.la
+
+pkgconfig_DATA = libxs.pc libxszmq.pc libzmq.pc
+
+include_HEADERS = ../include/xs.h ../include/xs_utils.h \
+ ../include/xszmq.h ../include/xszmq_utils.h \
+ ../include/zmq.h ../include/zmq_utils.h
+
+../include/zmq.h: ../include/xszmq.h
+ cp ../include/xszmq.h ../include/zmq.h
+
+../include/zmq_utils.h: ../include/xszmq_utils.h
+ cp ../include/xszmq_utils.h ../include/zmq_utils.h
+
+distclean-local:
+ -rm -f ../include/zmq.h ../include/zmq_utils.h
+else
+lib_LTLIBRARIES = libxs.la libxszmq.la
+
+pkgconfig_DATA = libxs.pc libxszmq.pc
+
+include_HEADERS = ../include/xs.h ../include/xs_utils.h \
+ ../include/xszmq.h ../include/xszmq_utils.h
+endif
libxs_la_SOURCES = \
array.hpp \
@@ -132,9 +153,9 @@ libxs_la_SOURCES = \
xs_utils.cpp
if ON_MINGW
-libxs_la_LDFLAGS = -no-undefined -avoid-version -version-info @LTVER@ @LIBXS_EXTRA_LDFLAGS@
+libxs_la_LDFLAGS = -no-undefined -avoid-version -version-info @LIBXS_ABI_VERSION@ @LIBXS_EXTRA_LDFLAGS@
else
-libxs_la_LDFLAGS = -version-info @LTVER@ @LIBXS_EXTRA_LDFLAGS@
+libxs_la_LDFLAGS = -version-info @LIBXS_ABI_VERSION@ @LIBXS_EXTRA_LDFLAGS@
endif
libxs_la_CXXFLAGS = @LIBXS_EXTRA_CXXFLAGS@
@@ -144,6 +165,23 @@ libxs_la_CPPFLAGS = -I$(top_srcdir)/@pgm_srcdir@/include/
libxs_la_LIBADD = $(top_srcdir)/@pgm_srcdir@/libpgm_noinst.la
endif
+libxszmq_la_SOURCES = xszmq.c
+libxszmq_la_CPPFLAGS = -DXS_BUILDING_LIBXSZMQ
+libxszmq_la_LIBADD = libxs.la
+
+if ON_MINGW
+libxszmq_la_LDFLAGS = -no-undefined -avoid-version -version-info @LIBXSZMQ_ABI_VERSION@
+else
+libxszmq_la_LDFLAGS = -version-info @LIBXSZMQ_ABI_VERSION@
+endif
+
+if BUILD_LIBZMQ
+libzmq_la_SOURCES = $(libxszmq_la_SOURCES)
+libzmq_la_CPPFLAGS = $(libxszmq_la_CPPFLAGS)
+libzmq_la_LIBADD = $(libxszmq_la_LIBADD)
+libzmq_la_LDFLAGS = $(libxszmq_la_LDFLAGS)
+endif
+
dist-hook:
-rm $(distdir)/platform.hpp
diff --git a/src/libxszmq.pc.in b/src/libxszmq.pc.in
new file mode 100644
index 0000000..9c631ad
--- /dev/null
+++ b/src/libxszmq.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libxszmq
+Description: Crossroads libxszmq compatibility library
+Version: @VERSION@
+Libs: -L${libdir} -lxszmq
+Cflags: -I${includedir}
diff --git a/src/libzmq.pc.in b/src/libzmq.pc.in
new file mode 100644
index 0000000..b282680
--- /dev/null
+++ b/src/libzmq.pc.in
@@ -0,0 +1,10 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: libzmq
+Description: Crossroads libzmq compatibility library
+Version: @VERSION@
+Libs: -L${libdir} -lzmq
+Cflags: -I${includedir}
diff --git a/src/xszmq.c b/src/xszmq.c
new file mode 100644
index 0000000..d97d9ea
--- /dev/null
+++ b/src/xszmq.c
@@ -0,0 +1,443 @@
+/*
+ Copyright (c) 2012 250bpm s.r.o.
+ Copyright (c) 2012 Martin Lucina
+ Copyright (c) 2012 Other contributors as noted in the AUTHORS file
+
+ This file is part of Crossroads I/O project.
+
+ Crossroads I/O 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 3 of the License, or
+ (at your option) any later version.
+
+ Crossroads 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 this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../include/xszmq.h"
+#include "../include/xszmq_utils.h"
+
+#include "../include/xs.h"
+#include "../include/xs_utils.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+void zmq_version (int *major_, int *minor_, int *patch_)
+{
+ *major_ = ZMQ_VERSION_MAJOR;
+ *minor_ = ZMQ_VERSION_MINOR;
+ *patch_ = ZMQ_VERSION_PATCH;
+}
+
+int zmq_errno ()
+{
+ return xs_errno ();
+}
+
+const char *zmq_strerror (int errnum)
+{
+ return xs_strerror (errnum);
+}
+
+int zmq_msg_init (zmq_msg_t *msg)
+{
+ xs_msg_t *content = (xs_msg_t*) malloc (sizeof (xs_msg_t));
+ assert (content);
+ int rc = xs_msg_init (content);
+ if (rc != 0)
+ return -1;
+ msg->content = (void*) content;
+ return 0;
+}
+
+int zmq_msg_init_size (zmq_msg_t *msg, size_t size)
+{
+ xs_msg_t *content = (xs_msg_t*) malloc (sizeof (xs_msg_t));
+ assert (content);
+ int rc = xs_msg_init_size (content, size);
+ if (rc != 0)
+ return -1;
+ msg->content = (void*) content;
+ return 0;
+}
+
+int zmq_msg_init_data (zmq_msg_t *msg, void *data,
+ size_t size, zmq_free_fn *ffn, void *hint)
+{
+ xs_msg_t *content = (xs_msg_t*) malloc (sizeof (xs_msg_t));
+ assert (content);
+ int rc = xs_msg_init_data (content, data, size, ffn, hint);
+ if (rc != 0)
+ return -1;
+ msg->content = (void*) content;
+ return 0;
+}
+
+int zmq_msg_close (zmq_msg_t *msg)
+{
+ int rc = xs_msg_close ((xs_msg_t*) msg->content);
+ if (rc != 0)
+ return -1;
+ free (msg->content);
+ msg->content = NULL;
+ return 0;
+}
+
+int zmq_msg_move (zmq_msg_t *dest, zmq_msg_t *src)
+{
+ return xs_msg_move ((xs_msg_t*) dest->content, (xs_msg_t*) src->content);
+}
+
+int zmq_msg_copy (zmq_msg_t *dest, zmq_msg_t *src)
+{
+ return xs_msg_copy ((xs_msg_t*) dest->content, (xs_msg_t*) src->content);
+}
+
+void *zmq_msg_data (zmq_msg_t *msg)
+{
+ return xs_msg_data ((xs_msg_t*) msg->content);
+}
+
+size_t zmq_msg_size (zmq_msg_t *msg)
+{
+ return xs_msg_size ((xs_msg_t*) msg->content);
+}
+
+void *zmq_init (int io_threads)
+{
+ return xs_init (io_threads);
+}
+
+int zmq_term (void *context)
+{
+ return xs_term (context);
+}
+
+void *zmq_socket (void *context, int type)
+{
+ return xs_socket (context, type);
+}
+
+int zmq_close (void *s)
+{
+ return xs_close (s);
+}
+
+int zmq_setsockopt (void *s, int option, const void *optval,
+ size_t optvallen)
+{
+ switch (option) {
+
+ case ZMQ_AFFINITY:
+ case ZMQ_IDENTITY:
+ case ZMQ_SUBSCRIBE:
+ case ZMQ_UNSUBSCRIBE:
+ case ZMQ_LINGER:
+ case ZMQ_RECONNECT_IVL:
+ case ZMQ_RECONNECT_IVL_MAX:
+ case ZMQ_BACKLOG:
+ return xs_setsockopt (s, option, optval, optvallen);
+
+ case ZMQ_HWM:
+ {
+ if (optvallen != sizeof (uint64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val = (int) *(uint64_t*) optval;
+ int rc = xs_setsockopt (s, XS_SNDHWM, &val, sizeof (int));
+ if (rc < 0)
+ return -1;
+ return xs_setsockopt (s, XS_RCVHWM, &val, sizeof (int));
+ }
+
+ case ZMQ_RATE:
+ {
+ if (optvallen != sizeof (int64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val = (int) *(int64_t*) optval;
+ return xs_setsockopt (s, option, &val, sizeof (int));
+ }
+
+ case ZMQ_RECOVERY_IVL:
+ {
+ if (optvallen != sizeof (int64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val = ((int) *(int64_t*) optval) * 1000;
+ return xs_setsockopt (s, option, &val, sizeof (int));
+ }
+
+ case ZMQ_RECOVERY_IVL_MSEC:
+ {
+ if (optvallen != sizeof (int64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val = (int) *(int64_t*) optval;
+ return xs_setsockopt (s, option, &val, sizeof (int));
+ }
+
+ case ZMQ_SNDBUF:
+ case ZMQ_RCVBUF:
+ {
+ if (optvallen != sizeof (uint64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val = (int) *(uint64_t*) optval;
+ return xs_setsockopt (s, option, &val, sizeof (int));
+ }
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int zmq_getsockopt (void *s, int option, void *optval,
+ size_t *optvallen)
+{
+ switch (option)
+ {
+ case ZMQ_TYPE:
+ case ZMQ_AFFINITY:
+ case ZMQ_IDENTITY:
+ case ZMQ_FD:
+ case ZMQ_BACKLOG:
+ case ZMQ_LINGER:
+ case ZMQ_RECONNECT_IVL:
+ case ZMQ_RECONNECT_IVL_MAX:
+ return xs_getsockopt (s, option, optval, optvallen);
+
+ case ZMQ_RCVMORE:
+ case ZMQ_RATE:
+ {
+ if (!optvallen || *optvallen < sizeof (int64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val;
+ size_t size;
+ int rc = xs_getsockopt (s, option, &val, &size);
+ if (rc < 0)
+ return -1;
+ assert (size == sizeof (int));
+ *(int64_t*) optval = (int64_t) val;
+ *optvallen = sizeof (int64_t);
+ return 0;
+ }
+
+ case ZMQ_HWM:
+ {
+ if (!optvallen || *optvallen < sizeof (uint64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val;
+ size_t size;
+ int rc = xs_getsockopt (s, XS_SNDHWM, &val, &size);
+ if (rc < 0)
+ return -1;
+ assert (size == sizeof (int));
+ *(uint64_t*) optval = (uint64_t) val;
+ *optvallen = sizeof (uint64_t);
+ return 0;
+ }
+
+ case ZMQ_RECOVERY_IVL:
+ {
+ if (!optvallen || *optvallen < sizeof (int64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val;
+ size_t size;
+ int rc = xs_getsockopt (s, option, &val, &size);
+ if (rc < 0)
+ return -1;
+ val /= 1000;
+ assert (size == sizeof (int));
+ *(int64_t*) optval = (int64_t) val;
+ *optvallen = sizeof (int64_t);
+ return 0;
+ }
+
+ case ZMQ_RECOVERY_IVL_MSEC:
+ {
+ if (!optvallen || *optvallen < sizeof (int64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val;
+ size_t size;
+ int rc = xs_getsockopt (s, option, &val, &size);
+ if (rc < 0)
+ return -1;
+ assert (size == sizeof (int));
+ *(int64_t*) optval = (int64_t) val;
+ *optvallen = sizeof (int64_t);
+ return 0;
+ }
+
+ case ZMQ_SNDBUF:
+ case ZMQ_RCVBUF:
+ {
+ if (!optvallen || *optvallen < sizeof (uint64_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val;
+ size_t size;
+ int rc = xs_getsockopt (s, option, &val, &size);
+ if (rc < 0)
+ return -1;
+ assert (size == sizeof (int));
+ *(int64_t*) optval = (uint64_t) val;
+ *optvallen = sizeof (uint64_t);
+ return 0;
+ }
+
+ case ZMQ_EVENTS:
+ {
+ if (!optvallen || *optvallen < sizeof (uint32_t)) {
+ errno = EINVAL;
+ return -1;
+ }
+ int val;
+ size_t size;
+ int rc = xs_getsockopt (s, option, &val, &size);
+ if (rc < 0)
+ return -1;
+ assert (size == sizeof (int));
+ *(int32_t*) optval = (uint32_t) val;
+ *optvallen = sizeof (uint32_t);
+ return 0;
+ }
+
+ default:
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+int zmq_bind (void *s, const char *addr)
+{
+ return xs_bind (s, addr);
+}
+
+int zmq_connect (void *s, const char *addr)
+{
+ return xs_connect (s, addr);
+}
+
+int zmq_send (void *s, zmq_msg_t *msg, int flags)
+{
+ int rc = xs_sendmsg (s, (xs_msg_t*) msg->content, flags);
+ return rc < 0 ? -1 : 0;
+}
+
+int zmq_recv (void *s, zmq_msg_t *msg, int flags)
+{
+ int rc = xs_recvmsg (s, (xs_msg_t*) msg->content, flags);
+ return rc < 0 ? -1 : 0;
+}
+
+int zmq_poll (zmq_pollitem_t *items, int nitems, long timeout)
+{
+ return xs_poll ((xs_pollitem_t*) items, nitems, timeout / 1000);
+}
+
+int zmq_device (int device, void *frontend, void *backend)
+{
+ int more;
+ size_t size;
+ xs_msg_t msg;
+ xs_pollitem_t items [2];
+
+ int rc = xs_msg_init (&msg);
+ if (rc != 0)
+ return -1;
+
+ items [0].socket = frontend;
+ items [0].events = XS_POLLIN;
+ items [1].socket = backend;
+ items [1].events = XS_POLLIN;
+
+ while (1) {
+
+ rc = xs_poll (&items [0], 2, -1);
+ if (rc < 0)
+ return -1;
+
+ if (items [0].revents & XS_POLLIN) {
+ while (1) {
+
+ rc = xs_recvmsg (frontend, &msg, 0);
+ if (rc < 0)
+ return -1;
+
+ size = sizeof (more);
+ rc = xs_getsockopt (frontend, XS_RCVMORE, &more, &size);
+ if (rc < 0)
+ return -1;
+
+ rc = xs_sendmsg (backend, &msg, more ? XS_SNDMORE : 0);
+ if (rc < 0)
+ return -1;
+
+ if (!more)
+ break;
+ }
+ }
+
+ if (items [1].revents & XS_POLLIN) {
+ while (1) {
+
+ rc = xs_recvmsg (backend, &msg, 0);
+ if (rc < 0)
+ return -1;
+
+ size = sizeof (more);
+ rc = xs_getsockopt (backend, XS_RCVMORE, &more, &size);
+ if (rc < 0)
+ return -1;
+
+ rc = xs_sendmsg (frontend, &msg, more ? ZMQ_SNDMORE : 0);
+ if (rc < 0)
+ return -1;
+
+ if (!more)
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+void *zmq_stopwatch_start ()
+{
+ return xs_stopwatch_start ();
+}
+
+unsigned long zmq_stopwatch_stop (void *watch)
+{
+ return xs_stopwatch_stop (watch);
+}
+
+void zmq_sleep (int seconds)
+{
+ xs_sleep (seconds);
+}
+