mirror of
https://github.com/haiwen/libsearpc.git
synced 2025-08-22 14:15:51 +00:00
Compare commits
76 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
d799dff145 | ||
|
6f06843849 | ||
|
255d5dedd2 | ||
|
0deb45d89f | ||
|
36706a9f32 | ||
|
d00c062d76 | ||
|
7f275255f0 | ||
|
c917575246 | ||
|
ed12cfba81 | ||
|
4ccd1988d8 | ||
|
7fd078664b | ||
|
cb1ffb2676 | ||
|
783141fb69 | ||
|
d6ba8f60dc | ||
|
d78aede0e4 | ||
|
ae466d2b3b | ||
|
97e15aa5a9 | ||
|
15f6f0b9f4 | ||
|
54145b03f4 | ||
|
e72c1158c8 | ||
|
e889dbcb50 | ||
|
50ff08b03c | ||
|
29f0c14b37 | ||
|
7e2bcb0991 | ||
|
b0079d2a0c | ||
|
9a307a916c | ||
|
719921a984 | ||
|
c5d031eaa2 | ||
|
d1fd7518a2 | ||
|
9e62d54bcf | ||
|
c206362c99 | ||
|
c72e6b6978 | ||
|
35a19401d6 | ||
|
8b853cf41d | ||
|
3291d04cec | ||
|
9b2e2dc652 | ||
|
23f581b39f | ||
|
501fa31d03 | ||
|
f7c20fa391 | ||
|
fbbdafd2ab | ||
|
f10068c3f6 | ||
|
fb7242cd09 | ||
|
b4b8548368 | ||
|
317877f996 | ||
|
19598f1d9d | ||
|
12d4c33f6e | ||
|
60ba8eca57 | ||
|
5b21fe6e69 | ||
|
1239667823 | ||
|
c137594507 | ||
|
faaff4cf7b | ||
|
c185be9413 | ||
|
2803f8d5cf | ||
|
2e1f32b83a | ||
|
0c26e154cb | ||
|
c161cb90a5 | ||
|
212281a882 | ||
|
361fdf86de | ||
|
e0d45991aa | ||
|
20be6d2edf | ||
|
6c5fea320c | ||
|
bc8f815777 | ||
|
777c9accaa | ||
|
ac0750d058 | ||
|
4f32f8be00 | ||
|
ebe09c82d5 | ||
|
55b97e1849 | ||
|
85127befda | ||
|
474bf337d8 | ||
|
22cfe9adbe | ||
|
041fd68e1c | ||
|
d19a3d1a2c | ||
|
980203eaf7 | ||
|
45bdce573f | ||
|
10e7432cab | ||
|
2021fe4aa8 |
@ -1,5 +1,9 @@
|
|||||||
sudo: false
|
sudo: false
|
||||||
language: python
|
language: python
|
||||||
|
python:
|
||||||
|
- "2.7"
|
||||||
|
- "3.5"
|
||||||
|
- "3.6"
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang
|
||||||
@ -7,6 +11,8 @@ addons:
|
|||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- libjansson-dev
|
- libjansson-dev
|
||||||
|
install:
|
||||||
|
- pip install future
|
||||||
before_install:
|
before_install:
|
||||||
- git clean -x -f
|
- git clean -x -f
|
||||||
- ./autogen.sh
|
- ./autogen.sh
|
||||||
|
@ -18,12 +18,5 @@ endif
|
|||||||
|
|
||||||
SUBDIRS = lib pysearpc ${MAKE_DEMO} tests
|
SUBDIRS = lib pysearpc ${MAKE_DEMO} tests
|
||||||
|
|
||||||
install-data-local:
|
|
||||||
if MACOS
|
|
||||||
sed -i '' -e "s|(DESTDIR)|${DESTDIR}|g" $(pcfiles)
|
|
||||||
else
|
|
||||||
${SED} -i "s|(DESTDIR)|${DESTDIR}|g" $(pcfiles)
|
|
||||||
endif
|
|
||||||
|
|
||||||
dist-hook:
|
dist-hook:
|
||||||
git log -1 > $(distdir)/latest_commit
|
git log -1 > $(distdir)/latest_commit
|
||||||
|
33
configure.ac
33
configure.ac
@ -42,6 +42,15 @@ AC_ARG_ENABLE(server-pkg,
|
|||||||
AC_HELP_STRING([--enable-server-pkg], [enable static compile]),
|
AC_HELP_STRING([--enable-server-pkg], [enable static compile]),
|
||||||
[server_pkg=$enableval],[server_pkg="no"])
|
[server_pkg=$enableval],[server_pkg="no"])
|
||||||
|
|
||||||
|
# option: compile-universal
|
||||||
|
# default: no
|
||||||
|
AC_ARG_ENABLE([compile-universal],
|
||||||
|
[AS_HELP_STRING([--enable-compile-universal],
|
||||||
|
[compile seafile universal @<:@default: no@:>@])],
|
||||||
|
[compile_universal=${enableval}], [compile_universal=no])
|
||||||
|
|
||||||
|
AM_CONDITIONAL([COMPILE_UNIVERSAL], [test x${compile_universal} = xyes])
|
||||||
|
|
||||||
dnl - check if the macro WIN32 is defined on this compiler.
|
dnl - check if the macro WIN32 is defined on this compiler.
|
||||||
AC_MSG_CHECKING(for WIN32)
|
AC_MSG_CHECKING(for WIN32)
|
||||||
|
|
||||||
@ -69,6 +78,23 @@ fi
|
|||||||
AM_CONDITIONAL([MACOS], [test "$bmac" = "yes"])
|
AM_CONDITIONAL([MACOS], [test "$bmac" = "yes"])
|
||||||
AC_SUBST(MACOS)
|
AC_SUBST(MACOS)
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(for FreeBSD)
|
||||||
|
|
||||||
|
if test "$(uname -s)" = "FreeBSD"; then
|
||||||
|
bfbsd=yes
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test x$bfbsd = "xyes"; then
|
||||||
|
server_pkg=no
|
||||||
|
AC_MSG_RESULT(compile in FreeBSD)
|
||||||
|
fi
|
||||||
|
|
||||||
|
AM_CONDITIONAL([FBSD], [test "$bfbsd" = "yes"])
|
||||||
|
AC_SUBST(FBSD)
|
||||||
|
|
||||||
|
AC_ARG_WITH([python3], [AS_HELP_STRING([--with-python3], [use python3])],
|
||||||
|
[with_python3="yes"],[])
|
||||||
|
|
||||||
# Checks for libraries.
|
# Checks for libraries.
|
||||||
|
|
||||||
GLIB_REQUIRED=2.26.0
|
GLIB_REQUIRED=2.26.0
|
||||||
@ -84,7 +110,12 @@ PKG_CHECK_MODULES(JANSSON, [jansson >= $JANSSON_REQUIRED])
|
|||||||
AC_SUBST(JANSSON_CFLAGS)
|
AC_SUBST(JANSSON_CFLAGS)
|
||||||
AC_SUBST(JANSSON_LIBS)
|
AC_SUBST(JANSSON_LIBS)
|
||||||
|
|
||||||
AM_PATH_PYTHON([2.4])
|
if test "$with_python3" = "yes"; then
|
||||||
|
AM_PATH_PYTHON([3.5])
|
||||||
|
else
|
||||||
|
AM_PATH_PYTHON([2.7])
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$bwin32" = true; then
|
if test "$bwin32" = true; then
|
||||||
if test x$PYTHON_DIR != x; then
|
if test x$PYTHON_DIR != x; then
|
||||||
# set pyexecdir to somewhere like /c/Python26/Lib/site-packages
|
# set pyexecdir to somewhere like /c/Python26/Lib/site-packages
|
||||||
|
6
debian/changelog
vendored
6
debian/changelog
vendored
@ -1,3 +1,9 @@
|
|||||||
|
libsearpc1 (3.2.0) unstable; urgency=low
|
||||||
|
|
||||||
|
* new upstream release
|
||||||
|
|
||||||
|
-- Jonathan Xu <jonathan.xu@seafile.com> Thu, 24 Oct 2019 11:05:10 +0800
|
||||||
|
|
||||||
libsearpc1 (3.1.0) unstable; urgency=low
|
libsearpc1 (3.1.0) unstable; urgency=low
|
||||||
|
|
||||||
* new upstream release
|
* new upstream release
|
||||||
|
7
debian/control
vendored
7
debian/control
vendored
@ -4,10 +4,11 @@ Priority: extra
|
|||||||
Maintainer: m.eik michalke <meik.michalke@hhu.de>
|
Maintainer: m.eik michalke <meik.michalke@hhu.de>
|
||||||
Build-Depends:
|
Build-Depends:
|
||||||
debhelper (>= 7),
|
debhelper (>= 7),
|
||||||
|
dh-python,
|
||||||
autotools-dev,
|
autotools-dev,
|
||||||
intltool,
|
intltool,
|
||||||
libglib2.0-dev,
|
libglib2.0-dev,
|
||||||
python,
|
python3 (>= 3.5),
|
||||||
libtool,
|
libtool,
|
||||||
libjansson-dev
|
libjansson-dev
|
||||||
Standards-Version: 3.9.5
|
Standards-Version: 3.9.5
|
||||||
@ -30,7 +31,7 @@ Section: libdevel
|
|||||||
Architecture: any
|
Architecture: any
|
||||||
Depends:
|
Depends:
|
||||||
${misc:Depends},
|
${misc:Depends},
|
||||||
python (>= 2.7),
|
python3 (>= 3.5),
|
||||||
libsearpc1 (= ${binary:Version})
|
libsearpc1 (= ${binary:Version})
|
||||||
Conflicts: seafile
|
Conflicts: seafile
|
||||||
Description: Development files for the libsearpc1 package.
|
Description: Development files for the libsearpc1 package.
|
||||||
@ -49,7 +50,7 @@ Package: python-searpc
|
|||||||
Section: python
|
Section: python
|
||||||
Multi-Arch: foreign
|
Multi-Arch: foreign
|
||||||
Architecture: all
|
Architecture: all
|
||||||
Depends: ${python:Depends},
|
Depends: ${python3:Depends},
|
||||||
${shlibs:Depends},
|
${shlibs:Depends},
|
||||||
${misc:Depends}
|
${misc:Depends}
|
||||||
Description: simple and easy-to-use C language RPC framework
|
Description: simple and easy-to-use C language RPC framework
|
||||||
|
2
debian/python-searpc.install
vendored
2
debian/python-searpc.install
vendored
@ -1 +1 @@
|
|||||||
usr/lib/python*/dist-packages/pysearpc/*.py
|
usr/lib/python3*/site-packages/pysearpc/*.py usr/lib/python3/dist-packages/pysearpc
|
||||||
|
4
debian/rules
vendored
4
debian/rules
vendored
@ -2,11 +2,11 @@
|
|||||||
# -*- makefile -*-
|
# -*- makefile -*-
|
||||||
|
|
||||||
%:
|
%:
|
||||||
dh $@ --with python2 --with autotools_dev --builddirectory=build
|
dh $@ --with python3 --with autotools_dev --builddirectory=build
|
||||||
|
|
||||||
override_dh_auto_configure:
|
override_dh_auto_configure:
|
||||||
./autogen.sh
|
./autogen.sh
|
||||||
dh_auto_configure -- --disable-compile-demo
|
dh_auto_configure -- --disable-compile-demo --with-python3
|
||||||
|
|
||||||
override_dh_strip:
|
override_dh_strip:
|
||||||
# emptying the dependency_libs field in .la files
|
# emptying the dependency_libs field in .la files
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
GType test_object_get_type (void);
|
||||||
|
|
||||||
#define TEST_OBJECT_TYPE (test_object_get_type())
|
#define TEST_OBJECT_TYPE (test_object_get_type())
|
||||||
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_OBJECT_TYPE, TestObject))
|
#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_OBJECT_TYPE, TestObject))
|
||||||
#define IS_TEST_OBJCET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_OBJCET_TYPE))
|
#define IS_TEST_OBJCET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_OBJCET_TYPE))
|
||||||
|
@ -2,8 +2,13 @@
|
|||||||
AM_CFLAGS = @GLIB_CFLAGS@ \
|
AM_CFLAGS = @GLIB_CFLAGS@ \
|
||||||
@JANSSON_CFLAGS@ \
|
@JANSSON_CFLAGS@ \
|
||||||
-I${top_builddir}/lib \
|
-I${top_builddir}/lib \
|
||||||
-I${top_srcdir}/lib \
|
-I${top_srcdir}/lib
|
||||||
-DG_LOG_DOMAIN=\"Searpc\"
|
|
||||||
|
if MACOS
|
||||||
|
if COMPILE_UNIVERSAL
|
||||||
|
AM_CFLAGS += -arch x86_64 -arch arm64
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
lib_LTLIBRARIES = libsearpc.la
|
lib_LTLIBRARIES = libsearpc.la
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ static void clean_objlist(GList *list)
|
|||||||
|
|
||||||
|
|
||||||
SearpcClient *
|
SearpcClient *
|
||||||
searpc_client_new ()
|
searpc_client_new (void)
|
||||||
{
|
{
|
||||||
return g_new0 (SearpcClient, 1);
|
return g_new0 (SearpcClient, 1);
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,16 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBSEARPC_EXPORTS
|
||||||
|
#define LIBSEARPC_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define LIBSEARPC_API
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DFT_DOMAIN
|
#ifndef DFT_DOMAIN
|
||||||
#define DFT_DOMAIN g_quark_from_string(G_LOG_DOMAIN)
|
#define DFT_DOMAIN g_quark_from_string(G_LOG_DOMAIN)
|
||||||
#endif
|
#endif
|
||||||
@ -31,85 +41,88 @@ struct _SearpcClient {
|
|||||||
void *async_arg;
|
void *async_arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _SearpcClient SearpcClient;
|
typedef struct _SearpcClient LIBSEARPC_API SearpcClient;
|
||||||
|
|
||||||
SearpcClient *searpc_client_new ();
|
LIBSEARPC_API
|
||||||
|
SearpcClient *searpc_client_new (void);
|
||||||
|
|
||||||
void searpc_client_free (SearpcClient *client);
|
LIBSEARPC_API void
|
||||||
|
searpc_client_free (SearpcClient *client);
|
||||||
|
|
||||||
void
|
LIBSEARPC_API void
|
||||||
searpc_client_call (SearpcClient *client, const char *fname,
|
searpc_client_call (SearpcClient *client, const char *fname,
|
||||||
const char *ret_type, GType gobject_type,
|
const char *ret_type, GType gobject_type,
|
||||||
void *ret_ptr, GError **error,
|
void *ret_ptr, GError **error,
|
||||||
int n_params, ...);
|
int n_params, ...);
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_call__int (SearpcClient *client, const char *fname,
|
searpc_client_call__int (SearpcClient *client, const char *fname,
|
||||||
GError **error, int n_params, ...);
|
GError **error, int n_params, ...);
|
||||||
|
|
||||||
gint64
|
LIBSEARPC_API gint64
|
||||||
searpc_client_call__int64 (SearpcClient *client, const char *fname,
|
searpc_client_call__int64 (SearpcClient *client, const char *fname,
|
||||||
GError **error, int n_params, ...);
|
GError **error, int n_params, ...);
|
||||||
|
|
||||||
char *
|
LIBSEARPC_API char *
|
||||||
searpc_client_call__string (SearpcClient *client, const char *fname,
|
searpc_client_call__string (SearpcClient *client, const char *fname,
|
||||||
GError **error, int n_params, ...);
|
GError **error, int n_params, ...);
|
||||||
|
|
||||||
GObject *
|
LIBSEARPC_API GObject *
|
||||||
searpc_client_call__object (SearpcClient *client, const char *fname,
|
searpc_client_call__object (SearpcClient *client, const char *fname,
|
||||||
GType object_type,
|
GType object_type,
|
||||||
GError **error, int n_params, ...);
|
GError **error, int n_params, ...);
|
||||||
|
|
||||||
GList*
|
LIBSEARPC_API GList*
|
||||||
searpc_client_call__objlist (SearpcClient *client, const char *fname,
|
searpc_client_call__objlist (SearpcClient *client, const char *fname,
|
||||||
GType object_type,
|
GType object_type,
|
||||||
GError **error, int n_params, ...);
|
GError **error, int n_params, ...);
|
||||||
|
|
||||||
json_t *
|
LIBSEARPC_API json_t *
|
||||||
searpc_client_call__json (SearpcClient *client, const char *fname,
|
searpc_client_call__json (SearpcClient *client, const char *fname,
|
||||||
GError **error, int n_params, ...);
|
GError **error, int n_params, ...);
|
||||||
|
|
||||||
|
|
||||||
char* searpc_client_transport_send (SearpcClient *client,
|
LIBSEARPC_API char*
|
||||||
|
searpc_client_transport_send (SearpcClient *client,
|
||||||
const gchar *fcall_str,
|
const gchar *fcall_str,
|
||||||
size_t fcall_len,
|
size_t fcall_len,
|
||||||
size_t *ret_len);
|
size_t *ret_len);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_async_call__int (SearpcClient *client,
|
searpc_client_async_call__int (SearpcClient *client,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
AsyncCallback callback, void *cbdata,
|
AsyncCallback callback, void *cbdata,
|
||||||
int n_params, ...);
|
int n_params, ...);
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_async_call__int64 (SearpcClient *client,
|
searpc_client_async_call__int64 (SearpcClient *client,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
AsyncCallback callback, void *cbdata,
|
AsyncCallback callback, void *cbdata,
|
||||||
int n_params, ...);
|
int n_params, ...);
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_async_call__string (SearpcClient *client,
|
searpc_client_async_call__string (SearpcClient *client,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
AsyncCallback callback, void *cbdata,
|
AsyncCallback callback, void *cbdata,
|
||||||
int n_params, ...);
|
int n_params, ...);
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_async_call__object (SearpcClient *client,
|
searpc_client_async_call__object (SearpcClient *client,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
AsyncCallback callback,
|
AsyncCallback callback,
|
||||||
GType object_type, void *cbdata,
|
GType object_type, void *cbdata,
|
||||||
int n_params, ...);
|
int n_params, ...);
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_async_call__objlist (SearpcClient *client,
|
searpc_client_async_call__objlist (SearpcClient *client,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
AsyncCallback callback,
|
AsyncCallback callback,
|
||||||
GType object_type, void *cbdata,
|
GType object_type, void *cbdata,
|
||||||
int n_params, ...);
|
int n_params, ...);
|
||||||
|
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_async_call__json (SearpcClient *client,
|
searpc_client_async_call__json (SearpcClient *client,
|
||||||
const char *fname,
|
const char *fname,
|
||||||
AsyncCallback callback, void *cbdata,
|
AsyncCallback callback, void *cbdata,
|
||||||
@ -118,7 +131,7 @@ searpc_client_async_call__json (SearpcClient *client,
|
|||||||
|
|
||||||
/* called by the transport layer, the rpc layer should be able to
|
/* called by the transport layer, the rpc layer should be able to
|
||||||
* modify the str, but not take ownership of it */
|
* modify the str, but not take ownership of it */
|
||||||
int
|
LIBSEARPC_API int
|
||||||
searpc_client_generic_callback (char *retstr, size_t len,
|
searpc_client_generic_callback (char *retstr, size_t len,
|
||||||
void *vdata, const char *errstr);
|
void *vdata, const char *errstr);
|
||||||
|
|
||||||
@ -128,5 +141,9 @@ searpc_client_generic_callback (char *retstr, size_t len,
|
|||||||
#define TRANSPORT_ERROR "Transport Error"
|
#define TRANSPORT_ERROR "Transport Error"
|
||||||
#define TRANSPORT_ERROR_CODE 500
|
#define TRANSPORT_ERROR_CODE 500
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -139,7 +139,7 @@ def generate_marshal_register_item(ret_type, arg_types):
|
|||||||
signature_name=signature_name)
|
signature_name=signature_name)
|
||||||
|
|
||||||
def gen_marshal_register_function(f):
|
def gen_marshal_register_function(f):
|
||||||
write_file(f, "static void register_marshals()""")
|
write_file(f, "static void register_marshals(void)""")
|
||||||
write_file(f, "{")
|
write_file(f, "{")
|
||||||
for item in func_table:
|
for item in func_table:
|
||||||
write_file(f, generate_marshal_register_item(item[0], item[1]))
|
write_file(f, generate_marshal_register_item(item[0], item[1]))
|
||||||
@ -147,7 +147,7 @@ def gen_marshal_register_function(f):
|
|||||||
|
|
||||||
signature_template = r"""
|
signature_template = r"""
|
||||||
inline static gchar *
|
inline static gchar *
|
||||||
${signature_name}()
|
${signature_name}(void)
|
||||||
{
|
{
|
||||||
return searpc_compute_signature (${args});
|
return searpc_compute_signature (${args});
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,13 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/epoll.h>
|
||||||
|
#endif
|
||||||
#endif // !defined(WIN32)
|
#endif // !defined(WIN32)
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
#include <glib/gstdio.h>
|
#include <glib/gstdio.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
@ -32,7 +37,9 @@ static char* formatErrorMessage();
|
|||||||
#endif // defined(WIN32)
|
#endif // defined(WIN32)
|
||||||
|
|
||||||
static void* named_pipe_listen(void *arg);
|
static void* named_pipe_listen(void *arg);
|
||||||
static void* named_pipe_client_handler(void *arg);
|
static void* handle_named_pipe_client_with_thread (void *arg);
|
||||||
|
static void handle_named_pipe_client_with_threadpool(void *data, void *user_data);
|
||||||
|
static void named_pipe_client_handler (void *data);
|
||||||
static char* searpc_named_pipe_send(void *arg, const gchar *fcall_str, size_t fcall_len, size_t *ret_len);
|
static char* searpc_named_pipe_send(void *arg, const gchar *fcall_str, size_t fcall_len, size_t *ret_len);
|
||||||
|
|
||||||
static char * request_to_json(const char *service, const char *fcall_str, size_t fcall_len);
|
static char * request_to_json(const char *service, const char *fcall_str, size_t fcall_len);
|
||||||
@ -40,8 +47,8 @@ static int request_from_json (const char *content, size_t len, char **service, c
|
|||||||
static void json_object_set_string_member (json_t *object, const char *key, const char *value);
|
static void json_object_set_string_member (json_t *object, const char *key, const char *value);
|
||||||
static const char * json_object_get_string_member (json_t *object, const char *key);
|
static const char * json_object_get_string_member (json_t *object, const char *key);
|
||||||
|
|
||||||
static ssize_t pipe_write_n(SearpcNamedPipe fd, const void *vptr, size_t n);
|
static gssize pipe_write_n(SearpcNamedPipe fd, const void *vptr, size_t n);
|
||||||
static ssize_t pipe_read_n(SearpcNamedPipe fd, void *vptr, size_t n);
|
static gssize pipe_read_n(SearpcNamedPipe fd, void *vptr, size_t n);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SearpcNamedPipeClient* client;
|
SearpcNamedPipeClient* client;
|
||||||
@ -74,6 +81,33 @@ SearpcNamedPipeServer* searpc_create_named_pipe_server(const char *path)
|
|||||||
{
|
{
|
||||||
SearpcNamedPipeServer *server = g_malloc0(sizeof(SearpcNamedPipeServer));
|
SearpcNamedPipeServer *server = g_malloc0(sizeof(SearpcNamedPipeServer));
|
||||||
memcpy(server->path, path, strlen(path) + 1);
|
memcpy(server->path, path, strlen(path) + 1);
|
||||||
|
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
SearpcNamedPipeServer* searpc_create_named_pipe_server_with_threadpool (const char *path, int named_pipe_server_thread_pool_size)
|
||||||
|
{
|
||||||
|
GError *error = NULL;
|
||||||
|
|
||||||
|
SearpcNamedPipeServer *server = g_malloc0(sizeof(SearpcNamedPipeServer));
|
||||||
|
memcpy(server->path, path, strlen(path) + 1);
|
||||||
|
server->pool_size = named_pipe_server_thread_pool_size;
|
||||||
|
server->named_pipe_server_thread_pool = g_thread_pool_new (handle_named_pipe_client_with_threadpool,
|
||||||
|
NULL,
|
||||||
|
named_pipe_server_thread_pool_size,
|
||||||
|
FALSE,
|
||||||
|
&error);
|
||||||
|
if (!server->named_pipe_server_thread_pool) {
|
||||||
|
if (error) {
|
||||||
|
g_warning ("Falied to create named pipe server thread pool : %s\n", error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
} else {
|
||||||
|
g_warning ("Falied to create named pipe server thread pool.\n");
|
||||||
|
}
|
||||||
|
g_free (server);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return server;
|
return server;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +133,7 @@ int searpc_named_pipe_server_start(SearpcNamedPipeServer *server)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (g_file_test (un_path, G_FILE_TEST_EXISTS)) {
|
if (g_file_test (un_path, G_FILE_TEST_EXISTS)) {
|
||||||
g_debug ("socket file exists, delete it anyway\n");
|
g_message ("socket file exists, delete it anyway\n");
|
||||||
if (g_unlink (un_path) < 0) {
|
if (g_unlink (un_path) < 0) {
|
||||||
g_warning ("delete socket file failed : %s\n", strerror(errno));
|
g_warning ("delete socket file failed : %s\n", strerror(errno));
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -124,6 +158,28 @@ int searpc_named_pipe_server_start(SearpcNamedPipeServer *server)
|
|||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
if (server->use_epoll) {
|
||||||
|
int epoll_fd;
|
||||||
|
struct epoll_event event;
|
||||||
|
|
||||||
|
epoll_fd = epoll_create1(0);
|
||||||
|
if (epoll_fd < 0) {
|
||||||
|
g_warning ("failed to open an epoll file descriptor: %s\n", strerror(errno));
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.events = EPOLLIN;
|
||||||
|
event.data.fd = pipe_fd;
|
||||||
|
if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, pipe_fd, &event) == -1) {
|
||||||
|
g_warning ("failed to add pipe fd to epoll list: %s\n", strerror(errno));
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
server->epoll_fd = epoll_fd;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
server->pipe_fd = pipe_fd;
|
server->pipe_fd = pipe_fd;
|
||||||
|
|
||||||
#endif // !defined(WIN32)
|
#endif // !defined(WIN32)
|
||||||
@ -140,26 +196,187 @@ failed:
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SearpcNamedPipeServer *server;
|
|
||||||
SearpcNamedPipe connfd;
|
SearpcNamedPipe connfd;
|
||||||
|
SearpcNamedPipeServer *server;
|
||||||
|
gboolean use_epoll;
|
||||||
} ServerHandlerData;
|
} ServerHandlerData;
|
||||||
|
|
||||||
|
// EPOLL
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
static void epoll_handler(void *data)
|
||||||
|
{
|
||||||
|
ServerHandlerData *handler_data = data;
|
||||||
|
SearpcNamedPipe connfd = handler_data->connfd;
|
||||||
|
SearpcNamedPipeServer *server = handler_data->server;
|
||||||
|
char *buf = NULL;
|
||||||
|
guint32 len = 0;
|
||||||
|
char *ret_str = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (pipe_read_n(connfd, &len, sizeof(guint32)) < 0) {
|
||||||
|
g_warning("failed to read rpc request size: %s\n", strerror(errno));
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len <= 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = g_new0 (char, len);
|
||||||
|
n = pipe_read_n (connfd, buf, len);
|
||||||
|
if (n < 0) {
|
||||||
|
g_warning ("failed to read rpc request: %s\n", strerror(errno));
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *service, *body;
|
||||||
|
if (request_from_json (buf, len, &service, &body) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
gsize ret_len;
|
||||||
|
ret_str = searpc_server_call_function (service, body, strlen(body), &ret_len);
|
||||||
|
g_free (service);
|
||||||
|
g_free (body);
|
||||||
|
|
||||||
|
len = (guint32)ret_len;
|
||||||
|
if (pipe_write_n (connfd, &len, sizeof(guint32)) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pipe_write_n (connfd, ret_str, ret_len) < 0) {
|
||||||
|
ret = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct epoll_event event;
|
||||||
|
event.events = EPOLLIN | EPOLLRDHUP;
|
||||||
|
event.data.ptr = (void *)handler_data;
|
||||||
|
|
||||||
|
if (epoll_ctl (server->epoll_fd, EPOLL_CTL_ADD, connfd, &event) == -1) {
|
||||||
|
ret = -1;
|
||||||
|
g_warning ("failed to add client fd to epoll list: %s\n", strerror(errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (buf);
|
||||||
|
if (ret < 0) {
|
||||||
|
close (connfd);
|
||||||
|
g_free (handler_data);
|
||||||
|
}
|
||||||
|
g_free (ret_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
epoll_listen (SearpcNamedPipeServer *server)
|
||||||
|
{
|
||||||
|
#define MAX_EVENTS 1000
|
||||||
|
struct epoll_event event;
|
||||||
|
struct epoll_event events[MAX_EVENTS];
|
||||||
|
int connfd;
|
||||||
|
int n_events;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
n_events = epoll_wait (server->epoll_fd, events, MAX_EVENTS, 1000);
|
||||||
|
if (n_events <= 0) {
|
||||||
|
if (n_events < 0) {
|
||||||
|
g_warning ("Failed to call waits for events on the epoll: %s\n", strerror(errno));
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (i = 0; i < n_events; i++) {
|
||||||
|
if (events[i].data.fd == server->pipe_fd) {
|
||||||
|
if (!(events[i].events & EPOLLIN)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// new client connection
|
||||||
|
connfd = accept (server->pipe_fd, NULL, 0);
|
||||||
|
if (connfd < 0) {
|
||||||
|
g_warning ("Failed to accept new client connection: %s\n", strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
event.events = EPOLLIN | EPOLLRDHUP;
|
||||||
|
ServerHandlerData *data = g_new0(ServerHandlerData, 1);
|
||||||
|
data->use_epoll = TRUE;
|
||||||
|
data->connfd = connfd;
|
||||||
|
data->server = server;
|
||||||
|
event.data.ptr = (void *)data;
|
||||||
|
if (epoll_ctl (server->epoll_fd, EPOLL_CTL_ADD, connfd, &event) == -1) {
|
||||||
|
g_warning ("Failed to add client fd to epoll list: %s\n", strerror(errno));
|
||||||
|
epoll_ctl(server->epoll_fd, EPOLL_CTL_DEL, connfd, NULL);
|
||||||
|
close (connfd);
|
||||||
|
g_free (data);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ServerHandlerData *data = (ServerHandlerData *)events[i].data.ptr;
|
||||||
|
connfd = data->connfd;
|
||||||
|
if (events[i].events & (EPOLLHUP | EPOLLRDHUP)) {
|
||||||
|
g_free (data);
|
||||||
|
epoll_ctl(server->epoll_fd, EPOLL_CTL_DEL, connfd, NULL);
|
||||||
|
close (connfd);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// After socket is readable, remove the socket from the epoll.
|
||||||
|
// After the worker finishes processing the current request, we will add the socket back into the epoll.
|
||||||
|
epoll_ctl(server->epoll_fd, EPOLL_CTL_DEL, connfd, NULL);
|
||||||
|
if (server->named_pipe_server_thread_pool) {
|
||||||
|
if (g_thread_pool_get_num_threads (server->named_pipe_server_thread_pool) >= server->pool_size) {
|
||||||
|
g_warning("The rpc server thread pool is full, the maximum number of threads is %d\n", server->pool_size);
|
||||||
|
}
|
||||||
|
g_thread_pool_push (server->named_pipe_server_thread_pool, data, NULL);
|
||||||
|
} else {
|
||||||
|
pthread_t handler;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_create(&handler, &attr, handle_named_pipe_client_with_thread, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void* named_pipe_listen(void *arg)
|
static void* named_pipe_listen(void *arg)
|
||||||
{
|
{
|
||||||
SearpcNamedPipeServer *server = arg;
|
SearpcNamedPipeServer *server = arg;
|
||||||
|
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
|
#ifdef __linux__
|
||||||
|
if (server->use_epoll) {
|
||||||
|
epoll_listen (server);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
while (1) {
|
while (1) {
|
||||||
int connfd = accept (server->pipe_fd, NULL, 0);
|
int connfd = accept (server->pipe_fd, NULL, 0);
|
||||||
pthread_t *handler = g_malloc(sizeof(pthread_t));
|
|
||||||
ServerHandlerData *data = g_malloc(sizeof(ServerHandlerData));
|
ServerHandlerData *data = g_malloc(sizeof(ServerHandlerData));
|
||||||
data->server = server;
|
|
||||||
data->connfd = connfd;
|
data->connfd = connfd;
|
||||||
// TODO(low priority): Instead of using a thread to handle each client,
|
data->use_epoll = FALSE;
|
||||||
// use select(unix)/iocp(windows) to do it.
|
if (server->named_pipe_server_thread_pool) {
|
||||||
pthread_create(handler, NULL, named_pipe_client_handler, data);
|
if (g_thread_pool_get_num_threads (server->named_pipe_server_thread_pool) >= server->pool_size) {
|
||||||
server->handlers = g_list_append(server->handlers, handler);
|
g_warning("The rpc server thread pool is full, the maximum number of threads is %d\n", server->pool_size);
|
||||||
|
}
|
||||||
|
g_thread_pool_push (server->named_pipe_server_thread_pool, data, NULL);
|
||||||
|
} else {
|
||||||
|
pthread_t handler;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_create(&handler, &attr, handle_named_pipe_client_with_thread, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !defined(WIN32)
|
#else // !defined(WIN32)
|
||||||
while (1) {
|
while (1) {
|
||||||
HANDLE connfd = INVALID_HANDLE_VALUE;
|
HANDLE connfd = INVALID_HANDLE_VALUE;
|
||||||
@ -192,53 +409,79 @@ static void* named_pipe_listen(void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_debug ("Accepted a named pipe client\n");
|
/* g_debug ("Accepted a named pipe client\n"); */
|
||||||
|
|
||||||
pthread_t *handler = g_malloc(sizeof(pthread_t));
|
|
||||||
ServerHandlerData *data = g_malloc(sizeof(ServerHandlerData));
|
ServerHandlerData *data = g_malloc(sizeof(ServerHandlerData));
|
||||||
data->server = server;
|
|
||||||
data->connfd = connfd;
|
data->connfd = connfd;
|
||||||
// TODO(low priority): Instead of using a thread to handle each client,
|
data->use_epoll = FALSE;
|
||||||
// use select(unix)/iocp(windows) to do it.
|
if (server->named_pipe_server_thread_pool)
|
||||||
pthread_create(handler, NULL, named_pipe_client_handler, data);
|
g_thread_pool_push (server->named_pipe_server_thread_pool, data, NULL);
|
||||||
server->handlers = g_list_append(server->handlers, handler);
|
else {
|
||||||
|
pthread_t handler;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||||
|
pthread_create(&handler, &attr, handle_named_pipe_client_with_thread, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif // !defined(WIN32)
|
#endif // !defined(WIN32)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* named_pipe_client_handler(void *arg)
|
static void* handle_named_pipe_client_with_thread(void *arg)
|
||||||
{
|
{
|
||||||
ServerHandlerData *data = arg;
|
#ifdef __linux__
|
||||||
// SearpcNamedPipeServer *server = data->server;
|
ServerHandlerData *handler_data = arg;
|
||||||
SearpcNamedPipe connfd = data->connfd;
|
if (handler_data->use_epoll) {
|
||||||
|
epoll_handler (arg);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
named_pipe_client_handler(arg);
|
||||||
|
|
||||||
size_t len;
|
return NULL;
|
||||||
size_t bufsize = 4096;
|
}
|
||||||
|
|
||||||
|
static void handle_named_pipe_client_with_threadpool(void *data, void *user_data)
|
||||||
|
{
|
||||||
|
#ifdef __linux__
|
||||||
|
ServerHandlerData *handler_data = data;
|
||||||
|
if (handler_data->use_epoll) {
|
||||||
|
epoll_handler (data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
named_pipe_client_handler(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void named_pipe_client_handler(void *data)
|
||||||
|
{
|
||||||
|
ServerHandlerData *handler_data = data;
|
||||||
|
SearpcNamedPipe connfd = handler_data->connfd;
|
||||||
|
|
||||||
|
guint32 len;
|
||||||
|
guint32 bufsize = 4096;
|
||||||
char *buf = g_malloc(bufsize);
|
char *buf = g_malloc(bufsize);
|
||||||
|
|
||||||
g_debug ("start to serve on pipe client\n");
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
len = 0;
|
len = 0;
|
||||||
if (pipe_read_n(connfd, &len, sizeof(uint32_t)) < 0) {
|
if (pipe_read_n(connfd, &len, sizeof(guint32)) < 0) {
|
||||||
g_warning("failed to read rpc request size: %s", strerror(errno));
|
g_warning("failed to read rpc request size: %s\n", strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
g_debug("EOF reached, pipe connection lost");
|
/* g_debug("EOF reached, pipe connection lost"); */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (bufsize < len) {
|
while (bufsize < len) {
|
||||||
bufsize *= 2;
|
bufsize *= 2;
|
||||||
buf = realloc(buf, bufsize);
|
buf = g_realloc(buf, bufsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe_read_n(connfd, buf, len) < 0 || len == 0) {
|
if (pipe_read_n(connfd, buf, len) < 0 || len == 0) {
|
||||||
g_warning("failed to read rpc request: %s", strerror(errno));
|
g_warning("failed to read rpc request: %s\n", strerror(errno));
|
||||||
g_free (buf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,19 +490,20 @@ static void* named_pipe_client_handler(void *arg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ret_len;
|
gsize ret_len;
|
||||||
char *ret_str = searpc_server_call_function (service, body, strlen(body), &ret_len);
|
char *ret_str = searpc_server_call_function (service, body, strlen(body), &ret_len);
|
||||||
g_free (service);
|
g_free (service);
|
||||||
g_free (body);
|
g_free (body);
|
||||||
|
|
||||||
if (pipe_write_n(connfd, &ret_len, sizeof(uint32_t)) < 0) {
|
len = (guint32)ret_len;
|
||||||
g_warning("failed to send rpc response(%s): %s", ret_str, strerror(errno));
|
if (pipe_write_n(connfd, &len, sizeof(guint32)) < 0) {
|
||||||
|
g_warning("failed to send rpc response(%s): %s\n", ret_str, strerror(errno));
|
||||||
g_free (ret_str);
|
g_free (ret_str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe_write_n(connfd, ret_str, ret_len) < 0) {
|
if (pipe_write_n(connfd, ret_str, ret_len) < 0) {
|
||||||
g_warning("failed to send rpc response: %s", strerror(errno));
|
g_warning("failed to send rpc response: %s\n", strerror(errno));
|
||||||
g_free (ret_str);
|
g_free (ret_str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -273,11 +517,10 @@ static void* named_pipe_client_handler(void *arg)
|
|||||||
DisconnectNamedPipe(connfd);
|
DisconnectNamedPipe(connfd);
|
||||||
CloseHandle(connfd);
|
CloseHandle(connfd);
|
||||||
#endif // !defined(WIN32)
|
#endif // !defined(WIN32)
|
||||||
|
g_free (data);
|
||||||
return NULL;
|
g_free (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client)
|
int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client)
|
||||||
{
|
{
|
||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
@ -288,11 +531,14 @@ int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client)
|
|||||||
g_strlcpy (servaddr.sun_path, client->path, sizeof(servaddr.sun_path));
|
g_strlcpy (servaddr.sun_path, client->path, sizeof(servaddr.sun_path));
|
||||||
if (connect(client->pipe_fd, (struct sockaddr *)&servaddr, (socklen_t)sizeof(servaddr)) < 0) {
|
if (connect(client->pipe_fd, (struct sockaddr *)&servaddr, (socklen_t)sizeof(servaddr)) < 0) {
|
||||||
g_warning ("pipe client failed to connect to server: %s\n", strerror(errno));
|
g_warning ("pipe client failed to connect to server: %s\n", strerror(errno));
|
||||||
|
close(client->pipe_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // !defined(WIN32)
|
#else // !defined(WIN32)
|
||||||
SearpcNamedPipe pipe_fd;
|
SearpcNamedPipe pipe_fd;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
pipe_fd = CreateFile(
|
pipe_fd = CreateFile(
|
||||||
client->path, // pipe name
|
client->path, // pipe name
|
||||||
GENERIC_READ | // read and write access
|
GENERIC_READ | // read and write access
|
||||||
@ -303,14 +549,21 @@ int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client)
|
|||||||
0, // default attributes
|
0, // default attributes
|
||||||
NULL); // no template file
|
NULL); // no template file
|
||||||
|
|
||||||
if (pipe_fd == INVALID_HANDLE_VALUE) {
|
if (pipe_fd != INVALID_HANDLE_VALUE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait with default timeout (approx. 50ms) */
|
||||||
|
if (GetLastError() != ERROR_PIPE_BUSY || !WaitNamedPipe(client->path, NMPWAIT_USE_DEFAULT_WAIT)) {
|
||||||
G_WARNING_WITH_LAST_ERROR("Failed to connect to named pipe");
|
G_WARNING_WITH_LAST_ERROR("Failed to connect to named pipe");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DWORD mode = PIPE_READMODE_MESSAGE;
|
DWORD mode = PIPE_READMODE_MESSAGE;
|
||||||
if (!SetNamedPipeHandleState(pipe_fd, &mode, NULL, NULL)) {
|
if (!SetNamedPipeHandleState(pipe_fd, &mode, NULL, NULL)) {
|
||||||
G_WARNING_WITH_LAST_ERROR("Failed to set named pipe mode");
|
G_WARNING_WITH_LAST_ERROR("Failed to set named pipe mode");
|
||||||
|
CloseHandle (pipe_fd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,7 +571,7 @@ int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client)
|
|||||||
|
|
||||||
#endif // !defined(WIN32)
|
#endif // !defined(WIN32)
|
||||||
|
|
||||||
g_debug ("pipe client connected to server\n");
|
/* g_debug ("pipe client connected to server\n"); */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,6 +585,7 @@ void searpc_free_client_with_pipe_transport (SearpcClient *client)
|
|||||||
close(pipe_client->pipe_fd);
|
close(pipe_client->pipe_fd);
|
||||||
#endif
|
#endif
|
||||||
g_free (pipe_client);
|
g_free (pipe_client);
|
||||||
|
g_free (data->service);
|
||||||
g_free (data);
|
g_free (data);
|
||||||
searpc_client_free (client);
|
searpc_client_free (client);
|
||||||
}
|
}
|
||||||
@ -339,37 +593,36 @@ void searpc_free_client_with_pipe_transport (SearpcClient *client)
|
|||||||
char *searpc_named_pipe_send(void *arg, const gchar *fcall_str,
|
char *searpc_named_pipe_send(void *arg, const gchar *fcall_str,
|
||||||
size_t fcall_len, size_t *ret_len)
|
size_t fcall_len, size_t *ret_len)
|
||||||
{
|
{
|
||||||
g_debug ("searpc_named_pipe_send is called\n");
|
/* g_debug ("searpc_named_pipe_send is called\n"); */
|
||||||
ClientTransportData *data = arg;
|
ClientTransportData *data = arg;
|
||||||
SearpcNamedPipeClient *client = data->client;
|
SearpcNamedPipeClient *client = data->client;
|
||||||
|
|
||||||
char *json_str = request_to_json(data->service, fcall_str, fcall_len);
|
char *json_str = request_to_json(data->service, fcall_str, fcall_len);
|
||||||
size_t json_len = strlen(json_str);
|
guint32 len = (guint32)strlen(json_str);
|
||||||
|
|
||||||
uint32_t len = json_len;
|
if (pipe_write_n(client->pipe_fd, &len, sizeof(guint32)) < 0) {
|
||||||
if (pipe_write_n(client->pipe_fd, &len, sizeof(uint32_t)) < 0) {
|
g_warning("failed to send rpc call: %s\n", strerror(errno));
|
||||||
g_warning("failed to send rpc call: %s", strerror(errno));
|
|
||||||
free (json_str);
|
free (json_str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe_write_n(client->pipe_fd, json_str, json_len) < 0) {
|
if (pipe_write_n(client->pipe_fd, json_str, len) < 0) {
|
||||||
g_warning("failed to send rpc call: %s", strerror(errno));
|
g_warning("failed to send rpc call: %s\n", strerror(errno));
|
||||||
free (json_str);
|
free (json_str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free (json_str);
|
free (json_str);
|
||||||
|
|
||||||
if (pipe_read_n(client->pipe_fd, &len, sizeof(uint32_t)) < 0) {
|
if (pipe_read_n(client->pipe_fd, &len, sizeof(guint32)) < 0) {
|
||||||
g_warning("failed to read rpc response: %s", strerror(errno));
|
g_warning("failed to read rpc response: %s\n", strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *buf = g_malloc(len);
|
char *buf = g_malloc(len);
|
||||||
|
|
||||||
if (pipe_read_n(client->pipe_fd, buf, len) < 0) {
|
if (pipe_read_n(client->pipe_fd, buf, len) < 0) {
|
||||||
g_warning("failed to read rpc response: %s", strerror(errno));
|
g_warning("failed to read rpc response: %s\n", strerror(errno));
|
||||||
g_free (buf);
|
g_free (buf);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -437,11 +690,11 @@ json_object_get_string_member (json_t *object, const char *key)
|
|||||||
#if !defined(WIN32)
|
#if !defined(WIN32)
|
||||||
|
|
||||||
// Write "n" bytes to a descriptor.
|
// Write "n" bytes to a descriptor.
|
||||||
ssize_t
|
gssize
|
||||||
pipe_write_n(int fd, const void *vptr, size_t n)
|
pipe_write_n(int fd, const void *vptr, size_t n)
|
||||||
{
|
{
|
||||||
size_t nleft;
|
size_t nleft;
|
||||||
ssize_t nwritten;
|
gssize nwritten;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
|
|
||||||
ptr = vptr;
|
ptr = vptr;
|
||||||
@ -462,11 +715,11 @@ pipe_write_n(int fd, const void *vptr, size_t n)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read "n" bytes from a descriptor.
|
// Read "n" bytes from a descriptor.
|
||||||
ssize_t
|
gssize
|
||||||
pipe_read_n(int fd, void *vptr, size_t n)
|
pipe_read_n(int fd, void *vptr, size_t n)
|
||||||
{
|
{
|
||||||
size_t nleft;
|
size_t nleft;
|
||||||
ssize_t nread;
|
gssize nread;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
|
||||||
ptr = vptr;
|
ptr = vptr;
|
||||||
@ -488,7 +741,7 @@ pipe_read_n(int fd, void *vptr, size_t n)
|
|||||||
|
|
||||||
#else // !defined(WIN32)
|
#else // !defined(WIN32)
|
||||||
|
|
||||||
ssize_t pipe_read_n (SearpcNamedPipe fd, void *vptr, size_t n)
|
gssize pipe_read_n (SearpcNamedPipe fd, void *vptr, size_t n)
|
||||||
{
|
{
|
||||||
DWORD bytes_read;
|
DWORD bytes_read;
|
||||||
BOOL success = ReadFile(
|
BOOL success = ReadFile(
|
||||||
@ -509,7 +762,7 @@ ssize_t pipe_read_n (SearpcNamedPipe fd, void *vptr, size_t n)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t pipe_write_n(SearpcNamedPipe fd, const void *vptr, size_t n)
|
gssize pipe_write_n(SearpcNamedPipe fd, const void *vptr, size_t n)
|
||||||
{
|
{
|
||||||
DWORD bytes_written;
|
DWORD bytes_written;
|
||||||
BOOL success = WriteFile(
|
BOOL success = WriteFile(
|
||||||
@ -520,38 +773,14 @@ ssize_t pipe_write_n(SearpcNamedPipe fd, const void *vptr, size_t n)
|
|||||||
NULL); // not overlapped I/O
|
NULL); // not overlapped I/O
|
||||||
|
|
||||||
if (!success || bytes_written != (DWORD)n) {
|
if (!success || bytes_written != (DWORD)n) {
|
||||||
G_WARNING_WITH_LAST_ERROR("failed to read command from the pipe");
|
G_WARNING_WITH_LAST_ERROR("failed to write to named pipe");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FlushFileBuffers(fd);
|
FlushFileBuffers(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *locale_to_utf8 (const gchar *src)
|
|
||||||
{
|
|
||||||
if (!src)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
gsize bytes_read = 0;
|
|
||||||
gsize bytes_written = 0;
|
|
||||||
GError *error = NULL;
|
|
||||||
gchar *dst = NULL;
|
|
||||||
|
|
||||||
dst = g_locale_to_utf8
|
|
||||||
(src, /* locale specific string */
|
|
||||||
strlen(src), /* len of src */
|
|
||||||
&bytes_read, /* length processed */
|
|
||||||
&bytes_written, /* output length */
|
|
||||||
&error);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// http://stackoverflow.com/questions/3006229/get-a-text-from-the-error-code-returns-from-the-getlasterror-function
|
// http://stackoverflow.com/questions/3006229/get-a-text-from-the-error-code-returns-from-the-getlasterror-function
|
||||||
// The caller is responsible to free the returned message.
|
// The caller is responsible to free the returned message.
|
||||||
char* formatErrorMessage()
|
char* formatErrorMessage()
|
||||||
@ -564,11 +793,12 @@ char* formatErrorMessage()
|
|||||||
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
|
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
NULL,
|
NULL,
|
||||||
error_code,
|
error_code,
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
/* EN_US */
|
||||||
|
MAKELANGID(LANG_ENGLISH, 0x01),
|
||||||
buf,
|
buf,
|
||||||
sizeof(buf) - 1,
|
sizeof(buf) - 1,
|
||||||
NULL);
|
NULL);
|
||||||
return locale_to_utf8(buf);
|
return g_strdup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(WIN32)
|
#endif // !defined(WIN32)
|
||||||
|
@ -10,6 +10,16 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBSEARPC_EXPORTS
|
||||||
|
#define LIBSEARPC_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define LIBSEARPC_API
|
||||||
|
#endif
|
||||||
|
|
||||||
// Implementatin of a searpc transport based on named pipe. It uses unix domain
|
// Implementatin of a searpc transport based on named pipe. It uses unix domain
|
||||||
// sockets on linux/osx, and named pipes on windows.
|
// sockets on linux/osx, and named pipes on windows.
|
||||||
//
|
//
|
||||||
@ -30,14 +40,22 @@ typedef int SearpcNamedPipe;
|
|||||||
struct _SearpcNamedPipeServer {
|
struct _SearpcNamedPipeServer {
|
||||||
char path[4096];
|
char path[4096];
|
||||||
pthread_t listener_thread;
|
pthread_t listener_thread;
|
||||||
GList *handlers;
|
|
||||||
SearpcNamedPipe pipe_fd;
|
SearpcNamedPipe pipe_fd;
|
||||||
|
gboolean use_epoll;
|
||||||
|
int epoll_fd;
|
||||||
|
GThreadPool *named_pipe_server_thread_pool;
|
||||||
|
int pool_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _SearpcNamedPipeServer SearpcNamedPipeServer;
|
typedef struct _SearpcNamedPipeServer LIBSEARPC_API SearpcNamedPipeServer;
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
SearpcNamedPipeServer* searpc_create_named_pipe_server(const char *path);
|
SearpcNamedPipeServer* searpc_create_named_pipe_server(const char *path);
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
|
SearpcNamedPipeServer* searpc_create_named_pipe_server_with_threadpool(const char *path, int named_pipe_server_thread_pool_size);
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
int searpc_named_pipe_server_start(SearpcNamedPipeServer *server);
|
int searpc_named_pipe_server_start(SearpcNamedPipeServer *server);
|
||||||
|
|
||||||
// Client side interface.
|
// Client side interface.
|
||||||
@ -47,14 +65,22 @@ struct _SearpcNamedPipeClient {
|
|||||||
SearpcNamedPipe pipe_fd;
|
SearpcNamedPipe pipe_fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _SearpcNamedPipeClient SearpcNamedPipeClient;
|
typedef struct _SearpcNamedPipeClient LIBSEARPC_API SearpcNamedPipeClient;
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
SearpcNamedPipeClient* searpc_create_named_pipe_client(const char *path);
|
SearpcNamedPipeClient* searpc_create_named_pipe_client(const char *path);
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
SearpcClient * searpc_client_with_named_pipe_transport(SearpcNamedPipeClient *client, const char *service);
|
SearpcClient * searpc_client_with_named_pipe_transport(SearpcNamedPipeClient *client, const char *service);
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client);
|
int searpc_named_pipe_client_connect(SearpcNamedPipeClient *client);
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_free_client_with_pipe_transport (SearpcClient *client);
|
void searpc_free_client_with_pipe_transport (SearpcClient *client);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // SEARPC_NAMED_PIPE_TRANSPORT_H
|
#endif // SEARPC_NAMED_PIPE_TRANSPORT_H
|
||||||
|
@ -9,8 +9,10 @@
|
|||||||
#include "searpc-server.h"
|
#include "searpc-server.h"
|
||||||
#include "searpc-utils.h"
|
#include "searpc-utils.h"
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef __linux__
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct FuncItem;
|
struct FuncItem;
|
||||||
@ -34,6 +36,14 @@ typedef struct {
|
|||||||
static GHashTable *marshal_table;
|
static GHashTable *marshal_table;
|
||||||
static GHashTable *service_table;
|
static GHashTable *service_table;
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
static FILE *slow_log_fp = NULL;
|
||||||
|
static gint64 slow_threshold;
|
||||||
|
static GList *filtered_funcs;
|
||||||
|
static pthread_mutex_t slow_log_lock;
|
||||||
|
static gboolean log_to_stdout = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
func_item_free (FuncItem *item)
|
func_item_free (FuncItem *item)
|
||||||
{
|
{
|
||||||
@ -136,6 +146,9 @@ searpc_set_objlist_to_ret_object (json_t *object, GList *ret)
|
|||||||
void
|
void
|
||||||
searpc_set_json_to_ret_object (json_t *object, json_t *ret)
|
searpc_set_json_to_ret_object (json_t *object, json_t *ret)
|
||||||
{
|
{
|
||||||
|
if (ret == NULL)
|
||||||
|
json_object_set_new(object, "ret", json_null ());
|
||||||
|
else
|
||||||
json_object_set_new (object, "ret", ret);
|
json_object_set_new (object, "ret", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,8 +198,67 @@ searpc_server_init (RegisterMarshalFunc register_func)
|
|||||||
register_func ();
|
register_func ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
int
|
||||||
|
searpc_server_init_with_slow_log (RegisterMarshalFunc register_func,
|
||||||
|
const char *slow_log_path,
|
||||||
|
gint64 slow_threshold_in,
|
||||||
|
GList *filtered_funcs_in)
|
||||||
|
{
|
||||||
|
const char *log_to_stdout_env = g_getenv("SEAFILE_LOG_TO_STDOUT");
|
||||||
|
if (g_strcmp0(log_to_stdout_env, "true") == 0) {
|
||||||
|
slow_log_fp = stdout;
|
||||||
|
log_to_stdout = TRUE;
|
||||||
|
} else if (slow_log_path) {
|
||||||
|
slow_log_fp = fopen (slow_log_path, "a+");
|
||||||
|
if (!slow_log_fp) {
|
||||||
|
g_warning ("Failed to open RPC slow log file %s: %s\n", slow_log_path, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slow_threshold = slow_threshold_in;
|
||||||
|
filtered_funcs = filtered_funcs_in;
|
||||||
|
|
||||||
|
pthread_mutex_init (&slow_log_lock, NULL);
|
||||||
|
|
||||||
|
searpc_server_init (register_func);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
searpc_server_reopen_slow_log (const char *slow_log_path)
|
||||||
|
{
|
||||||
|
FILE *fp, *oldfp;
|
||||||
|
|
||||||
|
if (log_to_stdout) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fp = fopen (slow_log_path, "a+")) == NULL) {
|
||||||
|
g_warning ("Failed to open RPC slow log file %s\n", slow_log_path);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock (&slow_log_lock);
|
||||||
|
oldfp = slow_log_fp;
|
||||||
|
slow_log_fp = fp;
|
||||||
|
pthread_mutex_unlock (&slow_log_lock);
|
||||||
|
|
||||||
|
if (fclose(oldfp) < 0) {
|
||||||
|
g_warning ("Failed to close old RPC slow log file\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
searpc_server_final()
|
searpc_server_final(void)
|
||||||
{
|
{
|
||||||
g_hash_table_destroy (service_table);
|
g_hash_table_destroy (service_table);
|
||||||
g_hash_table_destroy (marshal_table);
|
g_hash_table_destroy (marshal_table);
|
||||||
@ -244,6 +316,53 @@ searpc_server_register_function (const char *svc_name,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
rpc_include_passwd (const char *fname) {
|
||||||
|
GList *ptr;
|
||||||
|
char *rpc_name;
|
||||||
|
|
||||||
|
for (ptr = filtered_funcs; ptr; ptr = ptr->next) {
|
||||||
|
rpc_name = ptr->data;
|
||||||
|
if (g_strcmp0 (fname, rpc_name) == 0) {
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_slow_log_if_necessary (const char *svc_name, const char *func, gsize len,
|
||||||
|
const struct timeval *start,
|
||||||
|
const struct timeval *intv)
|
||||||
|
{
|
||||||
|
char time_buf[64];
|
||||||
|
gint64 intv_in_usec = ((gint64)intv->tv_sec) * G_USEC_PER_SEC + (gint64)intv->tv_usec;
|
||||||
|
gint64 intv_in_msec = intv_in_usec/1000;
|
||||||
|
double intv_in_sec = ((double)intv_in_usec)/G_USEC_PER_SEC;
|
||||||
|
|
||||||
|
if (intv_in_msec < slow_threshold)
|
||||||
|
return;
|
||||||
|
|
||||||
|
strftime(time_buf, 64, "%Y/%m/%d %H:%M:%S", localtime(&start->tv_sec));
|
||||||
|
|
||||||
|
pthread_mutex_lock (&slow_log_lock);
|
||||||
|
|
||||||
|
if (log_to_stdout) {
|
||||||
|
fprintf (slow_log_fp, "[seafile-slow-rpc] ");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf (slow_log_fp, "[%s] \"%s\" %.*s %.3f\n",
|
||||||
|
time_buf, svc_name, (int)len, func, intv_in_sec);
|
||||||
|
fflush (slow_log_fp);
|
||||||
|
|
||||||
|
pthread_mutex_unlock (&slow_log_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Called by RPC transport. */
|
/* Called by RPC transport. */
|
||||||
char*
|
char*
|
||||||
searpc_server_call_function (const char *svc_name,
|
searpc_server_call_function (const char *svc_name,
|
||||||
@ -255,10 +374,12 @@ searpc_server_call_function (const char *svc_name,
|
|||||||
json_error_t jerror;
|
json_error_t jerror;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef __linux__
|
||||||
struct timeval start, end, intv;
|
struct timeval start, end, intv;
|
||||||
|
|
||||||
|
if (slow_log_fp) {
|
||||||
gettimeofday(&start, NULL);
|
gettimeofday(&start, NULL);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
service = g_hash_table_lookup (service_table, svc_name);
|
service = g_hash_table_lookup (service_table, svc_name);
|
||||||
@ -290,11 +411,14 @@ searpc_server_call_function (const char *svc_name,
|
|||||||
|
|
||||||
ret = fitem->marshal->mfunc (fitem->func, array, ret_len);
|
ret = fitem->marshal->mfunc (fitem->func, array, ret_len);
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef __linux__
|
||||||
|
if (slow_log_fp) {
|
||||||
|
if (!filtered_funcs || !rpc_include_passwd (fitem->fname)) {
|
||||||
gettimeofday(&end, NULL);
|
gettimeofday(&end, NULL);
|
||||||
timersub(&end, &start, &intv);
|
timersub(&end, &start, &intv);
|
||||||
g_debug ("[searpc] Time spend in call %s: %ds %dus\n",
|
print_slow_log_if_necessary (svc_name, func, len, &start, &intv);
|
||||||
fname, intv.tv_sec, intv.tv_usec);
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
json_decref(array);
|
json_decref(array);
|
||||||
|
@ -5,6 +5,16 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef LIBSEARPC_EXPORTS
|
||||||
|
#define LIBSEARPC_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define LIBSEARPC_API
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DFT_DOMAIN
|
#ifndef DFT_DOMAIN
|
||||||
#define DFT_DOMAIN g_quark_from_string(G_LOG_DOMAIN)
|
#define DFT_DOMAIN g_quark_from_string(G_LOG_DOMAIN)
|
||||||
#endif
|
#endif
|
||||||
@ -13,11 +23,17 @@ typedef gchar* (*SearpcMarshalFunc) (void *func, json_t *param_array,
|
|||||||
gsize *ret_len);
|
gsize *ret_len);
|
||||||
typedef void (*RegisterMarshalFunc) (void);
|
typedef void (*RegisterMarshalFunc) (void);
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_set_string_to_ret_object (json_t *object, char *ret);
|
void searpc_set_string_to_ret_object (json_t *object, char *ret);
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_set_int_to_ret_object (json_t *object, json_int_t ret);
|
void searpc_set_int_to_ret_object (json_t *object, json_int_t ret);
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_set_object_to_ret_object (json_t *object, GObject *ret);
|
void searpc_set_object_to_ret_object (json_t *object, GObject *ret);
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_set_objlist_to_ret_object (json_t *object, GList *ret);
|
void searpc_set_objlist_to_ret_object (json_t *object, GList *ret);
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_set_json_to_ret_object (json_t *object, json_t *ret);
|
void searpc_set_json_to_ret_object (json_t *object, json_t *ret);
|
||||||
|
LIBSEARPC_API
|
||||||
char *searpc_marshal_set_ret_common (json_t *object, gsize *len, GError *error);
|
char *searpc_marshal_set_ret_common (json_t *object, gsize *len, GError *error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,14 +41,33 @@ char *searpc_marshal_set_ret_common (json_t *object, gsize *len, GError *error);
|
|||||||
*
|
*
|
||||||
* Inititalize searpc server.
|
* Inititalize searpc server.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_server_init (RegisterMarshalFunc register_func);
|
void searpc_server_init (RegisterMarshalFunc register_func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* searpc_server_init_with_slow_log:
|
||||||
|
*
|
||||||
|
* Inititalize searpc server with slow log file.
|
||||||
|
*/
|
||||||
|
LIBSEARPC_API int
|
||||||
|
searpc_server_init_with_slow_log (RegisterMarshalFunc register_func,
|
||||||
|
const char *slow_log_path,
|
||||||
|
gint64 slow_threshold_in,
|
||||||
|
GList *filtered_funcs_in);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in log rotate.
|
||||||
|
*/
|
||||||
|
LIBSEARPC_API int
|
||||||
|
searpc_server_reopen_slow_log (const char *slow_log_path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* searpc_server_final:
|
* searpc_server_final:
|
||||||
*
|
*
|
||||||
* Free the server structure.
|
* Free the server structure.
|
||||||
*/
|
*/
|
||||||
void searpc_server_final ();
|
LIBSEARPC_API
|
||||||
|
void searpc_server_final (void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* searpc_create_service:
|
* searpc_create_service:
|
||||||
@ -42,6 +77,7 @@ void searpc_server_final ();
|
|||||||
*
|
*
|
||||||
* @svc_name: Service name.
|
* @svc_name: Service name.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
int searpc_create_service (const char *svc_name);
|
int searpc_create_service (const char *svc_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,6 +85,7 @@ int searpc_create_service (const char *svc_name);
|
|||||||
*
|
*
|
||||||
* Remove the service from the server.
|
* Remove the service from the server.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
void searpc_remove_service (const char *svc_name);
|
void searpc_remove_service (const char *svc_name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +96,7 @@ void searpc_remove_service (const char *svc_name);
|
|||||||
* @signature: the signature of the marshal, register_marshal() will take
|
* @signature: the signature of the marshal, register_marshal() will take
|
||||||
* owner of this string.
|
* owner of this string.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
gboolean searpc_server_register_marshal (gchar *signature,
|
gboolean searpc_server_register_marshal (gchar *signature,
|
||||||
SearpcMarshalFunc marshal);
|
SearpcMarshalFunc marshal);
|
||||||
|
|
||||||
@ -70,6 +108,7 @@ gboolean searpc_server_register_marshal (gchar *signature,
|
|||||||
* @signature: the signature of the function, register_function() will take
|
* @signature: the signature of the function, register_function() will take
|
||||||
* owner of this string.
|
* owner of this string.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
gboolean searpc_server_register_function (const char *service,
|
gboolean searpc_server_register_function (const char *service,
|
||||||
void* func,
|
void* func,
|
||||||
const gchar *fname,
|
const gchar *fname,
|
||||||
@ -86,6 +125,7 @@ gboolean searpc_server_register_function (const char *service,
|
|||||||
*
|
*
|
||||||
* Returns the serialized representatio of the returned value.
|
* Returns the serialized representatio of the returned value.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
gchar *searpc_server_call_function (const char *service,
|
gchar *searpc_server_call_function (const char *service,
|
||||||
gchar *func, gsize len, gsize *ret_len);
|
gchar *func, gsize len, gsize *ret_len);
|
||||||
|
|
||||||
@ -96,6 +136,11 @@ gchar *searpc_server_call_function (const char *service,
|
|||||||
*
|
*
|
||||||
* Compute function signature.
|
* Compute function signature.
|
||||||
*/
|
*/
|
||||||
|
LIBSEARPC_API
|
||||||
char* searpc_compute_signature (const gchar *ret_type, int pnum, ...);
|
char* searpc_compute_signature (const gchar *ret_type, int pnum, ...);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
@ -2,15 +2,23 @@
|
|||||||
#include <glib-object.h>
|
#include <glib-object.h>
|
||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
|
|
||||||
|
#ifdef LIBSEARPC_EXPORTS
|
||||||
|
#define LIBSEARPC_API __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define LIBSEARPC_API
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SEARPC_JSON_DOMAIN g_quark_from_string("SEARPC_JSON")
|
#define SEARPC_JSON_DOMAIN g_quark_from_string("SEARPC_JSON")
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SEARPC_JSON_ERROR_LOAD,
|
SEARPC_JSON_ERROR_LOAD,
|
||||||
SEARPC_JSON_ERROR_PACK,
|
SEARPC_JSON_ERROR_PACK,
|
||||||
SEARPC_JSON_ERROR_UPACK
|
SEARPC_JSON_ERROR_UPACK
|
||||||
} SEARPCJSONERROR;
|
} LIBSEARPC_API SEARPCJSONERROR;
|
||||||
|
|
||||||
|
LIBSEARPC_API
|
||||||
json_t *json_gobject_serialize (GObject *);
|
json_t *json_gobject_serialize (GObject *);
|
||||||
|
LIBSEARPC_API
|
||||||
GObject *json_gobject_deserialize (GType , json_t *);
|
GObject *json_gobject_deserialize (GType , json_t *);
|
||||||
|
|
||||||
inline static void setjetoge(const json_error_t *jerror, GError **error)
|
inline static void setjetoge(const json_error_t *jerror, GError **error)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
prefix=(DESTDIR)@prefix@
|
prefix=@prefix@
|
||||||
exec_prefix=@exec_prefix@
|
exec_prefix=@exec_prefix@
|
||||||
libdir=@libdir@
|
libdir=@libdir@
|
||||||
includedir=@includedir@
|
includedir=@includedir@
|
||||||
@ -8,4 +8,4 @@ Description: Simple C rpc library
|
|||||||
Version: @VERSION@
|
Version: @VERSION@
|
||||||
Libs: -L${libdir} -lsearpc
|
Libs: -L${libdir} -lsearpc
|
||||||
Cflags: -I${includedir} -I${includedir}/searpc
|
Cflags: -I${includedir} -I${includedir}/searpc
|
||||||
Requires: gobject-2.0 gio-2.0 jansson
|
Requires: gobject-2.0 >= 2.26.0 gio-2.0 jansson >= 2.2.1
|
||||||
|
31
libsearpc.sln
Normal file
31
libsearpc.sln
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 16
|
||||||
|
VisualStudioVersion = 16.0.29215.179
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libsearpc", "libsearpc.vcxproj", "{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Release|x64.Build.0 = Release|x64
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {393C05AB-0CCA-4180-93EF-57D9CB079042}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
137
libsearpc.vcxproj
Normal file
137
libsearpc.vcxproj
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>16.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{7E7BDAA2-D61E-466D-B138-CC2454CAB1D3}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v142</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<OutDir>$(ProjectDir)$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
|
||||||
|
<PropertyGroup Label="Vcpkg">
|
||||||
|
<VcpkgEnableManifest>true</VcpkgEnableManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;LIBSEARPC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<TargetMachine>MachineX86</TargetMachine>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>LIBSEARPC_EXPORTS;WIN32</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\include\glib-2.0;$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\lib\glib-2.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<PreprocessorDefinitions>LIBSEARPC_EXPORTS;WIN32</PreprocessorDefinitions>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\include\glib-2.0;$(ProjectDir)vcpkg_installed\x64-windows\x64-windows\lib\glib-2.0\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="lib\searpc-client.c" />
|
||||||
|
<ClCompile Include="lib\searpc-named-pipe-transport.c" />
|
||||||
|
<ClCompile Include="lib\searpc-server.c" />
|
||||||
|
<ClCompile Include="lib\searpc-utils.c" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="config.h" />
|
||||||
|
<ClInclude Include="lib\searpc-client.h" />
|
||||||
|
<ClInclude Include="lib\searpc-named-pipe-transport.h" />
|
||||||
|
<ClInclude Include="lib\searpc-server.h" />
|
||||||
|
<ClInclude Include="lib\searpc-utils.h" />
|
||||||
|
<ClInclude Include="lib\searpc.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
@ -1,5 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
from common import SearpcError
|
from .common import SearpcError
|
||||||
|
|
||||||
def _fret_int(ret_str):
|
def _fret_int(ret_str):
|
||||||
try:
|
try:
|
||||||
@ -7,10 +7,10 @@ def _fret_int(ret_str):
|
|||||||
except:
|
except:
|
||||||
raise SearpcError('Invalid response format')
|
raise SearpcError('Invalid response format')
|
||||||
|
|
||||||
if dicts.has_key('err_code'):
|
if 'err_code' in dicts:
|
||||||
raise SearpcError(dicts['err_msg'])
|
raise SearpcError(dicts['err_msg'])
|
||||||
|
|
||||||
if dicts.has_key('ret'):
|
if 'ret' in dicts:
|
||||||
return dicts['ret']
|
return dicts['ret']
|
||||||
else:
|
else:
|
||||||
raise SearpcError('Invalid response format')
|
raise SearpcError('Invalid response format')
|
||||||
@ -21,10 +21,10 @@ def _fret_string(ret_str):
|
|||||||
except:
|
except:
|
||||||
raise SearpcError('Invalid response format')
|
raise SearpcError('Invalid response format')
|
||||||
|
|
||||||
if dicts.has_key('err_code'):
|
if 'err_code' in dicts:
|
||||||
raise SearpcError(dicts['err_msg'])
|
raise SearpcError(dicts['err_msg'])
|
||||||
|
|
||||||
if dicts.has_key('ret'):
|
if 'ret' in dicts:
|
||||||
return dicts['ret']
|
return dicts['ret']
|
||||||
else:
|
else:
|
||||||
raise SearpcError('Invalid response format')
|
raise SearpcError('Invalid response format')
|
||||||
@ -61,7 +61,7 @@ def _fret_obj(ret_str):
|
|||||||
except:
|
except:
|
||||||
raise SearpcError('Invalid response format')
|
raise SearpcError('Invalid response format')
|
||||||
|
|
||||||
if dicts.has_key('err_code'):
|
if 'err_code' in dicts:
|
||||||
raise SearpcError(dicts['err_msg'])
|
raise SearpcError(dicts['err_msg'])
|
||||||
|
|
||||||
if dicts['ret']:
|
if dicts['ret']:
|
||||||
@ -75,7 +75,7 @@ def _fret_objlist(ret_str):
|
|||||||
except:
|
except:
|
||||||
raise SearpcError('Invalid response format')
|
raise SearpcError('Invalid response format')
|
||||||
|
|
||||||
if dicts.has_key('err_code'):
|
if 'err_code' in dicts:
|
||||||
raise SearpcError(dicts['err_msg'])
|
raise SearpcError(dicts['err_msg'])
|
||||||
|
|
||||||
l = []
|
l = []
|
||||||
@ -85,6 +85,19 @@ def _fret_objlist(ret_str):
|
|||||||
|
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
def _fret_json(ret_str):
|
||||||
|
try:
|
||||||
|
dicts = json.loads(ret_str)
|
||||||
|
except:
|
||||||
|
raise SearpcError('Invalid response format')
|
||||||
|
|
||||||
|
if 'err_code' in dicts:
|
||||||
|
raise SearpcError(dicts['err_msg'])
|
||||||
|
|
||||||
|
if dicts['ret']:
|
||||||
|
return dicts['ret']
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
def searpc_func(ret_type, param_types):
|
def searpc_func(ret_type, param_types):
|
||||||
|
|
||||||
@ -101,6 +114,8 @@ def searpc_func(ret_type, param_types):
|
|||||||
fret = _fret_int
|
fret = _fret_int
|
||||||
elif ret_type == "string":
|
elif ret_type == "string":
|
||||||
fret = _fret_string
|
fret = _fret_string
|
||||||
|
elif ret_type == "json":
|
||||||
|
fret = _fret_json
|
||||||
else:
|
else:
|
||||||
raise SearpcError('Invial return type')
|
raise SearpcError('Invial return type')
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ import os
|
|||||||
import socket
|
import socket
|
||||||
import struct
|
import struct
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
import queue
|
||||||
|
|
||||||
from .client import SearpcClient
|
from .client import SearpcClient
|
||||||
from .server import searpc_server
|
from .server import searpc_server
|
||||||
@ -36,52 +37,67 @@ class NamedPipeTransport(SearpcTransport):
|
|||||||
|
|
||||||
def __init__(self, socket_path):
|
def __init__(self, socket_path):
|
||||||
self.socket_path = socket_path
|
self.socket_path = socket_path
|
||||||
self.pipe_fd = None
|
self.pipe = None
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
self.pipe_fd = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
|
self.pipe = socket.socket(socket.AF_UNIX)
|
||||||
make_socket_closeonexec(self.pipe_fd)
|
self.pipe.connect(self.socket_path)
|
||||||
self.pipe_fd.connect(self.socket_path)
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.pipe_fd:
|
if self.pipe:
|
||||||
self.pipe_fd.close()
|
self.pipe.close()
|
||||||
self.pipe_fd = None
|
self.pipe = None
|
||||||
|
|
||||||
def send(self, service, fcall_str):
|
def send(self, service, fcall_str):
|
||||||
body = json.dumps({
|
body = json.dumps({
|
||||||
'service': service,
|
'service': service,
|
||||||
'request': fcall_str,
|
'request': fcall_str,
|
||||||
})
|
})
|
||||||
|
body_utf8 = body.encode(encoding='utf-8')
|
||||||
# "I" for unsiged int
|
# "I" for unsiged int
|
||||||
header = struct.pack('I', len(body))
|
header = struct.pack('=I', len(body_utf8))
|
||||||
sendall(self.pipe_fd, header)
|
sendall(self.pipe, header)
|
||||||
sendall(self.pipe_fd, body)
|
sendall(self.pipe, body_utf8)
|
||||||
|
|
||||||
resp_header = recvall(self.pipe_fd, 4)
|
resp_header = recvall(self.pipe, 4)
|
||||||
# logger.info('resp_header is %s', resp_header)
|
# logger.info('resp_header is %s', resp_header)
|
||||||
resp_size, = struct.unpack('I', resp_header)
|
resp_size, = struct.unpack('=I', resp_header)
|
||||||
# logger.info('resp_size is %s', resp_size)
|
# logger.info('resp_size is %s', resp_size)
|
||||||
resp = recvall(self.pipe_fd, resp_size)
|
resp = recvall(self.pipe, resp_size)
|
||||||
# logger.info('resp is %s', resp)
|
# logger.info('resp is %s', resp)
|
||||||
return resp
|
return resp.decode(encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
class NamedPipeClient(SearpcClient):
|
class NamedPipeClient(SearpcClient):
|
||||||
def __init__(self, socket_path, service_name):
|
def __init__(self, socket_path, service_name, pool_size=5):
|
||||||
self.socket_path = socket_path
|
self.socket_path = socket_path
|
||||||
self.service_name = service_name
|
self.service_name = service_name
|
||||||
self.transport = NamedPipeTransport(socket_path)
|
self.pool_size = pool_size
|
||||||
self.connected = False
|
self._pool = queue.Queue(pool_size)
|
||||||
|
|
||||||
def stop(self):
|
def _create_transport(self):
|
||||||
self.transport.stop()
|
transport = NamedPipeTransport(self.socket_path)
|
||||||
|
transport.connect()
|
||||||
|
return transport
|
||||||
|
|
||||||
|
def _get_transport(self):
|
||||||
|
try:
|
||||||
|
transport = self._pool.get(False)
|
||||||
|
except:
|
||||||
|
transport = self._create_transport()
|
||||||
|
return transport
|
||||||
|
|
||||||
|
def _return_transport(self, transport):
|
||||||
|
try:
|
||||||
|
self._pool.put(transport, False)
|
||||||
|
except queue.Full:
|
||||||
|
transport.stop()
|
||||||
|
|
||||||
def call_remote_func_sync(self, fcall_str):
|
def call_remote_func_sync(self, fcall_str):
|
||||||
if not self.connected:
|
transport = self._get_transport()
|
||||||
self.transport.connect()
|
ret_str = transport.send(self.service_name, fcall_str)
|
||||||
self.connected = True
|
self._return_transport(transport)
|
||||||
return self.transport.send(self.service_name, fcall_str)
|
return ret_str
|
||||||
|
|
||||||
|
|
||||||
class NamedPipeServer(object):
|
class NamedPipeServer(object):
|
||||||
@ -91,7 +107,7 @@ class NamedPipeServer(object):
|
|||||||
"""
|
"""
|
||||||
def __init__(self, socket_path):
|
def __init__(self, socket_path):
|
||||||
self.socket_path = socket_path
|
self.socket_path = socket_path
|
||||||
self.pipe_fd = None
|
self.pipe = None
|
||||||
self.thread = Thread(target=self.accept_loop)
|
self.thread = Thread(target=self.accept_loop)
|
||||||
self.thread.setDaemon(True)
|
self.thread.setDaemon(True)
|
||||||
|
|
||||||
@ -111,40 +127,40 @@ class NamedPipeServer(object):
|
|||||||
'Failed to remove existing unix socket {}'.
|
'Failed to remove existing unix socket {}'.
|
||||||
format(self.socket_path)
|
format(self.socket_path)
|
||||||
)
|
)
|
||||||
self.pipe_fd = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
|
self.pipe = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM, 0)
|
||||||
make_socket_closeonexec(self.pipe_fd)
|
make_socket_closeonexec(self.pipe)
|
||||||
self.pipe_fd.bind(self.socket_path)
|
self.pipe.bind(self.socket_path)
|
||||||
self.pipe_fd.listen(10)
|
self.pipe.listen(10)
|
||||||
logger.info('Server now listening at %s', self.socket_path)
|
logger.info('Server now listening at %s', self.socket_path)
|
||||||
|
|
||||||
def accept_loop(self):
|
def accept_loop(self):
|
||||||
logger.info('Waiting for clients')
|
logger.info('Waiting for clients')
|
||||||
while True:
|
while True:
|
||||||
connfd, _ = self.pipe_fd.accept()
|
connfd, _ = self.pipe.accept()
|
||||||
logger.info('New pip client')
|
logger.info('New pip client')
|
||||||
t = PipeHandlerThread(connfd)
|
t = PipeHandlerThread(connfd)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
|
|
||||||
class PipeHandlerThread(Thread):
|
class PipeHandlerThread(Thread):
|
||||||
def __init__(self, pipe_fd):
|
def __init__(self, pipe):
|
||||||
Thread.__init__(self)
|
Thread.__init__(self)
|
||||||
self.setDaemon(True)
|
self.setDaemon(True)
|
||||||
self.pipe_fd = pipe_fd
|
self.pipe = pipe
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
while True:
|
||||||
req_header = recvall(self.pipe_fd, 4)
|
req_header = recvall(self.pipe, 4)
|
||||||
# logger.info('Got req header %s', req_header)
|
# logger.info('Got req header %s', req_header)
|
||||||
req_size, = struct.unpack('I', req_header)
|
req_size, = struct.unpack('I', req_header)
|
||||||
# logger.info('req size is %s', req_size)
|
# logger.info('req size is %s', req_size)
|
||||||
req = recvall(self.pipe_fd, req_size)
|
req = recvall(self.pipe, req_size)
|
||||||
# logger.info('req is %s', req)
|
# logger.info('req is %s', req)
|
||||||
|
|
||||||
data = json.loads(req)
|
data = json.loads(req.decode(encoding='utf-8'))
|
||||||
resp = searpc_server.call_function(data['service'], data['request'])
|
resp = searpc_server.call_function(data['service'], data['request'])
|
||||||
# logger.info('resp is %s', resp)
|
# logger.info('resp is %s', resp)
|
||||||
|
|
||||||
resp_header = struct.pack('I', len(resp))
|
resp_header = struct.pack('I', len(resp))
|
||||||
sendall(self.pipe_fd, resp_header)
|
sendall(self.pipe, resp_header)
|
||||||
sendall(self.pipe_fd, resp)
|
sendall(self.pipe, resp.encode(encoding='utf-8'))
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -29,7 +28,7 @@ def gen_fcall_funcs_array(arg_types):
|
|||||||
pyfuncname = "fcall__" + "_".join(arg_types)
|
pyfuncname = "fcall__" + "_".join(arg_types)
|
||||||
tmplist = []
|
tmplist = []
|
||||||
for arg in arg_types:
|
for arg in arg_types:
|
||||||
tmplist.append(string.capitalize(arg))
|
tmplist.append(arg.capitalize())
|
||||||
|
|
||||||
cfuncname = "SearpcClient_Fcall__" + "_".join(tmplist)
|
cfuncname = "SearpcClient_Fcall__" + "_".join(tmplist)
|
||||||
|
|
||||||
@ -47,7 +46,7 @@ def gen_fret_funcs_array(ret_type):
|
|||||||
cfuncname = "SearpcClient_Fret__Void"
|
cfuncname = "SearpcClient_Fret__Void"
|
||||||
else:
|
else:
|
||||||
pyfuncname = "fret__" + ret_type
|
pyfuncname = "fret__" + ret_type
|
||||||
cfuncname = "SearpcClient_Fret__" + string.capitalize(ret_type)
|
cfuncname = "SearpcClient_Fret__" + ret_type.capitalize()
|
||||||
|
|
||||||
return string.Template(func_item_template)\
|
return string.Template(func_item_template)\
|
||||||
.substitute(pyfuncname=pyfuncname,
|
.substitute(pyfuncname=pyfuncname,
|
||||||
@ -79,8 +78,8 @@ def gen_module_funcs_array():
|
|||||||
array = fcall_array
|
array = fcall_array
|
||||||
array += fret_array
|
array += fret_array
|
||||||
|
|
||||||
print string.Template(module_func_array_template)\
|
print(string.Template(module_func_array_template)\
|
||||||
.substitute(array=array)
|
.substitute(array=array))
|
||||||
|
|
||||||
|
|
||||||
type_table = {
|
type_table = {
|
||||||
@ -128,7 +127,7 @@ def gen_fcall_func(arg_types):
|
|||||||
|
|
||||||
tmplist = []
|
tmplist = []
|
||||||
for arg in arg_types:
|
for arg in arg_types:
|
||||||
tmplist.append(string.capitalize(arg))
|
tmplist.append(arg.capitalize())
|
||||||
Suffix = "_".join(tmplist)
|
Suffix = "_".join(tmplist)
|
||||||
suffix = "_".join(arg_types)
|
suffix = "_".join(arg_types)
|
||||||
def_args = ""
|
def_args = ""
|
||||||
@ -161,7 +160,7 @@ def gen_fcall_list():
|
|||||||
arg_types_list.append(item[1])
|
arg_types_list.append(item[1])
|
||||||
|
|
||||||
for item in arg_types_list:
|
for item in arg_types_list:
|
||||||
print gen_fcall_func(item)
|
print(gen_fcall_func(item))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
|
|
||||||
from common import SearpcError
|
from .common import SearpcError
|
||||||
|
|
||||||
class SearpcService(object):
|
class SearpcService(object):
|
||||||
def __init__(self, name):
|
def __init__(self, name):
|
||||||
@ -25,7 +25,7 @@ class SearpcServer(object):
|
|||||||
"""input str -> output str"""
|
"""input str -> output str"""
|
||||||
try:
|
try:
|
||||||
argv = json.loads(fcallstr)
|
argv = json.loads(fcallstr)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
raise SearpcError('bad call str: ' + str(e))
|
raise SearpcError('bad call str: ' + str(e))
|
||||||
|
|
||||||
service = self.services[svcname]
|
service = self.services[svcname]
|
||||||
@ -41,7 +41,7 @@ class SearpcServer(object):
|
|||||||
def call_function(self, svcname, fcallstr):
|
def call_function(self, svcname, fcallstr):
|
||||||
try:
|
try:
|
||||||
retVal = self._call_function(svcname, fcallstr)
|
retVal = self._call_function(svcname, fcallstr)
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
ret = {'err_code': 555, 'err_msg': str(e)}
|
ret = {'err_code': 555, 'err_msg': str(e)}
|
||||||
else:
|
else:
|
||||||
ret = {'ret': retVal}
|
ret = {'ret': retVal}
|
||||||
|
@ -22,6 +22,14 @@ def init_server():
|
|||||||
searpc_server.create_service(SVCNAME)
|
searpc_server.create_service(SVCNAME)
|
||||||
searpc_server.register_function(SVCNAME, add, 'add')
|
searpc_server.register_function(SVCNAME, add, 'add')
|
||||||
searpc_server.register_function(SVCNAME, mul, 'multi')
|
searpc_server.register_function(SVCNAME, mul, 'multi')
|
||||||
|
searpc_server.register_function(SVCNAME, json_func, 'json_func')
|
||||||
|
searpc_server.register_function(SVCNAME, get_str, 'get_str')
|
||||||
|
|
||||||
|
def json_func(a, b):
|
||||||
|
return {'a': a, 'b': b}
|
||||||
|
|
||||||
|
def get_str():
|
||||||
|
return u'这是一个测试'
|
||||||
|
|
||||||
|
|
||||||
class DummyTransport(SearpcTransport):
|
class DummyTransport(SearpcTransport):
|
||||||
@ -40,6 +48,14 @@ class RpcMixin(object):
|
|||||||
def multi(self, x, y):
|
def multi(self, x, y):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@searpc_func("json", ["string", "int"])
|
||||||
|
def json_func(self, x, y):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@searpc_func("string", [])
|
||||||
|
def get_str(self):
|
||||||
|
pass
|
||||||
|
|
||||||
class DummyRpcClient(SearpcClient, RpcMixin):
|
class DummyRpcClient(SearpcClient, RpcMixin):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.transport = DummyTransport()
|
self.transport = DummyTransport()
|
||||||
@ -66,7 +82,6 @@ class SearpcTest(unittest.TestCase):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def tearDownClass(cls):
|
def tearDownClass(cls):
|
||||||
cls.named_pipe_client.stop()
|
|
||||||
cls.named_pipe_server.stop()
|
cls.named_pipe_server.stop()
|
||||||
|
|
||||||
def test_normal_transport(self):
|
def test_normal_transport(self):
|
||||||
@ -86,6 +101,12 @@ class SearpcTest(unittest.TestCase):
|
|||||||
v = client.multi('abc', 2)
|
v = client.multi('abc', 2)
|
||||||
self.assertEqual(v, 'abcabc')
|
self.assertEqual(v, 'abcabc')
|
||||||
|
|
||||||
|
v = client.json_func(1, 2)
|
||||||
|
self.assertEqual(v, json_func(1, 2))
|
||||||
|
|
||||||
|
v = client.get_str()
|
||||||
|
self.assertEqual(v, u'这是一个测试')
|
||||||
|
|
||||||
def setup_logging(level=logging.INFO):
|
def setup_logging(level=logging.INFO):
|
||||||
kw = {
|
kw = {
|
||||||
# 'format': '[%(asctime)s][%(pathname)s]: %(message)s',
|
# 'format': '[%(asctime)s][%(pathname)s]: %(message)s',
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
class SearpcTransport(object):
|
class SearpcTransport(object):
|
||||||
"""
|
"""
|
||||||
A transport is repsonsible to send the serialized request to the
|
A transport is repsonsible to send the serialized request to the
|
||||||
|
@ -5,7 +5,7 @@ from pysearpc.errors import NetworkError
|
|||||||
|
|
||||||
def recvall(fd, total):
|
def recvall(fd, total):
|
||||||
remain = total
|
remain = total
|
||||||
data = ''
|
data = bytearray()
|
||||||
while remain > 0:
|
while remain > 0:
|
||||||
try:
|
try:
|
||||||
new = fd.recv(remain)
|
new = fd.recv(remain)
|
||||||
@ -16,10 +16,10 @@ def recvall(fd, total):
|
|||||||
if n <= 0:
|
if n <= 0:
|
||||||
raise NetworkError("Failed to read from socket")
|
raise NetworkError("Failed to read from socket")
|
||||||
else:
|
else:
|
||||||
data += new
|
data.extend(new)
|
||||||
remain -= n
|
remain -= n
|
||||||
|
|
||||||
return data
|
return bytes(data)
|
||||||
|
|
||||||
def sendall(fd, data):
|
def sendall(fd, data):
|
||||||
total = len(data)
|
total = len(data)
|
||||||
|
@ -371,7 +371,7 @@ clar_test_init(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
clar_test_run()
|
clar_test_run(void)
|
||||||
{
|
{
|
||||||
if (_clar.argc > 1)
|
if (_clar.argc > 1)
|
||||||
clar_parse_args(_clar.argc, _clar.argv);
|
clar_parse_args(_clar.argc, _clar.argv);
|
||||||
@ -386,7 +386,7 @@ clar_test_run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clar_test_shutdown()
|
clar_test_shutdown(void)
|
||||||
{
|
{
|
||||||
clar_print_shutdown(
|
clar_print_shutdown(
|
||||||
_clar.tests_ran,
|
_clar.tests_ran,
|
||||||
|
@ -27,6 +27,8 @@ static const char *pipe_path = "\\\\.\\pipe\\libsearpc-test";
|
|||||||
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
|
#define MAMAN_IS_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MAMAN_TYPE_BAR))
|
||||||
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
|
#define MAMAN_BAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MAMAN_TYPE_BAR, MamanBarClass))
|
||||||
|
|
||||||
|
#define NAMED_PIPE_SERVER_THREAD_POOL_SIZE 50
|
||||||
|
|
||||||
typedef struct _MamanBar MamanBar;
|
typedef struct _MamanBar MamanBar;
|
||||||
typedef struct _MamanBarClass MamanBarClass;
|
typedef struct _MamanBarClass MamanBarClass;
|
||||||
|
|
||||||
@ -202,7 +204,7 @@ get_substring (const gchar *orig_str, int sub_len, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static SearpcClient *
|
static SearpcClient *
|
||||||
do_create_client_with_pipe_transport()
|
do_create_client_with_pipe_transport(void)
|
||||||
{
|
{
|
||||||
SearpcNamedPipeClient *pipe_client = searpc_create_named_pipe_client(pipe_path);
|
SearpcNamedPipeClient *pipe_client = searpc_create_named_pipe_client(pipe_path);
|
||||||
cl_must_pass_(searpc_named_pipe_client_connect(pipe_client), "named pipe client failed to connect");
|
cl_must_pass_(searpc_named_pipe_client_connect(pipe_client), "named pipe client failed to connect");
|
||||||
@ -545,7 +547,7 @@ test_searpc__initialize (void)
|
|||||||
client->async_send = sample_async_send;
|
client->async_send = sample_async_send;
|
||||||
client->async_arg = "test_async";
|
client->async_arg = "test_async";
|
||||||
|
|
||||||
SearpcNamedPipeServer *pipe_server = searpc_create_named_pipe_server(pipe_path);
|
SearpcNamedPipeServer *pipe_server = searpc_create_named_pipe_server_with_threadpool(pipe_path, NAMED_PIPE_SERVER_THREAD_POOL_SIZE);
|
||||||
cl_must_pass_(searpc_named_pipe_server_start(pipe_server), "named pipe server failed to start");
|
cl_must_pass_(searpc_named_pipe_server_start(pipe_server), "named pipe server failed to start");
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
// Wait for the server thread to start
|
// Wait for the server thread to start
|
||||||
|
18
vcpkg.json
Normal file
18
vcpkg.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"builtin-baseline": "f63682b9182187131b564c1395e4ac8ecb0c5ea8",
|
||||||
|
"dependencies": [
|
||||||
|
"glib",
|
||||||
|
"jansson",
|
||||||
|
"pthreads"
|
||||||
|
],
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"name": "jansson",
|
||||||
|
"version": "2.12-1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pthreads",
|
||||||
|
"version": "3.0.0-4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user