added memcached module
This commit is contained in:
		
							
								
								
									
										35
									
								
								configure.ac
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								configure.ac
									
									
									
									
									
								
							| @ -253,7 +253,7 @@ AC_CHECK_HEADERS([netinet/in.h sys/un.h netpacket/packet.h net/if.h net/if_dl.h | ||||
| 	#include <sys/types.h> | ||||
| 	#include <sys/socket.h>]) | ||||
| AC_CHECK_HEADERS([sys/stropts.h sys/macstat.h linux/ethtool.h linux/sockios.h]) | ||||
| AC_CHECK_HEADERS([ffi.h libunwind.h quadmath.h crt_externs.h uci.h]) | ||||
| AC_CHECK_HEADERS([ffi.h libunwind.h quadmath.h crt_externs.h uci.h libmemcached/memcached.h]) | ||||
|  | ||||
| dnl check data types | ||||
| dnl AC_CHECK_TYPE([wchar_t],  | ||||
| @ -384,6 +384,14 @@ AC_CHECK_LIB([uci], [uci_alloc_context], [UCI_LIBS="-luci"]) | ||||
| AC_SUBST(UCI_LIBS) | ||||
| AM_CONDITIONAL(HAVE_LIBUCI, test "x${ac_cv_lib_uci_uci_alloc_context}" = "xyes" -a "x${ac_cv_header_uci_h}" = "xyes") | ||||
|  | ||||
| dnl libmemcachd (optional) | ||||
| AC_CHECK_LIB([memcached], [memcached], | ||||
| 	[ | ||||
| 		MEMCACHED_LIBS="-lmemcached" | ||||
| 		AC_DEFINE([HAVE_MEMCACHED_LIB], [1], [libmemcached library is available]) | ||||
| 	]) | ||||
| AC_SUBST(MEMCACHED_LIBS) | ||||
|  | ||||
| AC_MSG_CHECKING([for va_copy]) | ||||
| AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>]], [[ | ||||
| 		va_list x, y; | ||||
| @ -1059,6 +1067,30 @@ then | ||||
| fi | ||||
| AM_CONDITIONAL(ENABLE_MOD_UCI, test "${enable_mod_uci_is}" = "yes") | ||||
|  | ||||
| dnl ===== enable-mod-memc ===== | ||||
| AC_ARG_ENABLE([mod-memc], | ||||
| 	[AS_HELP_STRING([--enable-mod-memc],[enable mod/memc. one of auto, yes, no (default. auto)])], | ||||
| 	enable_mod_memc_is=$enableval, | ||||
| 	enable_mod_memc_is=auto | ||||
| ) | ||||
| if test "x${enable_mod_memc_is}" = "xauto" | ||||
| then | ||||
| 	if test "x${ac_cv_header_libmemcached_memcached_h}" != "xyes" | ||||
| 	then | ||||
| 		enable_mod_memc_is="no" | ||||
| 	elif test "x${ac_cv_lib_memcached_memcached}" != "xyes" | ||||
| 	then | ||||
| 		enable_mod_memc_is="no" | ||||
| 	else | ||||
| 		enable_mod_memc_is="yes" | ||||
| 	fi | ||||
| fi | ||||
| if test "x${enable_mod_memc_is}" = "xyes" | ||||
| then | ||||
| 	AC_DEFINE([HAWK_ENABLE_MOD_MEMC],[1],[build mod/memc]) | ||||
| fi | ||||
| AM_CONDITIONAL(ENABLE_MOD_MEMC, test "${enable_mod_memc_is}" = "yes") | ||||
|  | ||||
|  | ||||
| dnl ==== include pthread options to the default flags ==== | ||||
| dnl keep this as  the last option as it changes the default compile flags.                                              dnl otherwise, other tests may get affected if this option is on.  | ||||
| @ -1112,5 +1144,6 @@ echo "  Math library: ${LIBM}" | ||||
| echo "  Socket library: ${SOCKET_LIBS}" | ||||
| echo "  Native function call library: ${FFI_LIBS}" | ||||
| echo "  Thraed library: ${PTHREAD_LIBS}" | ||||
| echo "  Memcached library: ${MEMCACHED_LIBS}" | ||||
| echo "-------------------------------------------------------------------------" | ||||
| ] | ||||
|  | ||||
| @ -236,6 +236,10 @@ if ENABLE_MOD_UCI | ||||
| libhawk_la_LIBADD += ../mod/libhawk-uci.la | ||||
| endif | ||||
|  | ||||
| if ENABLE_MOD_MEMC | ||||
| libhawk_la_LIBADD += ../mod/libhawk-memc.la | ||||
| endif | ||||
|  | ||||
| else | ||||
| ################################################## | ||||
| # DYNAMIC MODULES  | ||||
|  | ||||
| @ -7475,6 +7475,10 @@ int hawk_putsrcoochars (hawk_t* hawk, const hawk_ooch_t* str, hawk_oow_t len) | ||||
| #include "../mod/mod-uci.h" | ||||
| #endif | ||||
|  | ||||
| #if defined(HAWK_ENABLE_MOD_MEMC) | ||||
| #include "../mod/mod-memc.h" | ||||
| #endif | ||||
|  | ||||
| /* | ||||
|  * if modules are linked statically into the main hawk module, | ||||
|  * this table is used to find the entry point of the modules. | ||||
| @ -7503,6 +7507,9 @@ static struct | ||||
| #if defined(HAWK_ENABLE_MOD_UCI) | ||||
| 	{ HAWK_T("uci"),    hawk_mod_uci } | ||||
| #endif | ||||
| #if defined(HAWK_ENABLE_MOD_MEMC) | ||||
| 	{ HAWK_T("memc"),   hawk_mod_memc } | ||||
| #endif | ||||
| }; | ||||
| #endif | ||||
|  | ||||
|  | ||||
| @ -37,6 +37,10 @@ if ENABLE_MOD_UCI | ||||
| noinst_LTLIBRARIES += libhawk-uci.la | ||||
| endif | ||||
|  | ||||
| if ENABLE_MOD_MEMC | ||||
| noinst_LTLIBRARIES += libhawk-memc.la | ||||
| endif | ||||
|  | ||||
| ################################################## | ||||
| else | ||||
| ################################################## | ||||
| @ -66,6 +70,10 @@ if ENABLE_MOD_UCI | ||||
| pkgmodexec_LTLIBRARIES += libhawk-uci.la | ||||
| endif | ||||
|  | ||||
| if ENABLE_MOD_MEMC | ||||
| pkgmodexec_LTLIBRARIES += libhawk-memc.la | ||||
| endif | ||||
|  | ||||
| ################################################## | ||||
| endif | ||||
| ################################################## | ||||
| @ -105,3 +113,11 @@ libhawk_uci_la_CFLAGS = $(CFLAGS_COMMON) | ||||
| libhawk_uci_la_LDFLAGS = $(LDFLAGS_COMMON) | ||||
| libhawk_uci_la_LIBADD = $(LIBADD_COMMON) $(UCI_LIBS) | ||||
| endif | ||||
|  | ||||
| if ENABLE_MOD_MEMC | ||||
| libhawk_memc_la_SOURCES = mod-memc.c mod-memc.h | ||||
| libhawk_memc_la_CPPFLAGS = $(CPPFLAGS_COMMON) $(MEMCACHED_CFLAGS) | ||||
| libhawk_memc_la_CFLAGS = $(CFLAGS_COMMON) | ||||
| libhawk_memc_la_LDFLAGS = $(LDFLAGS_COMMON) $(MEMCACHED_LDFLAGS) | ||||
| libhawk_memc_la_LIBADD = $(LIBADD_COMMON) $(MEMCACHED_LIBS) | ||||
| endif | ||||
|  | ||||
							
								
								
									
										462
									
								
								mod/mod-memc.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										462
									
								
								mod/mod-memc.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,462 @@ | ||||
| /* | ||||
|  * $Id$ | ||||
|  * | ||||
|     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions | ||||
|     are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|        notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|        notice, this list of conditions and the following disclaimer in the | ||||
|        documentation and/or other materials provided with the distribution. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||
|     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
|     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||
|     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
|     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||
|     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #include "mod-memc.h" | ||||
| #include "../lib/hawk-prv.h" | ||||
|  | ||||
| #include <libmemcached/memcached.h> | ||||
|  | ||||
| #define __IDMAP_NODE_T_DATA  memcached_st *memc; | ||||
| #define __IDMAP_LIST_T_DATA  memcached_return_t rc; hawk_ooch_t errmsg[256]; | ||||
| #define __IDMAP_LIST_T memc_list_t | ||||
| #define __IDMAP_NODE_T memc_node_t | ||||
| #define __INIT_IDMAP_LIST __init_memc_list | ||||
| #define __FINI_IDMAP_LIST __fini_memc_list | ||||
| #define __MAKE_IDMAP_NODE __new_memc_node | ||||
| #define __FREE_IDMAP_NODE __free_memc_node | ||||
| #include "../lib/idmap-imp.h" | ||||
|  | ||||
| struct rtx_data_t | ||||
| { | ||||
| 	memc_list_t memc_list; | ||||
| }; | ||||
| typedef struct rtx_data_t rtx_data_t; | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| static memc_node_t* new_memc_node (hawk_rtx_t* rtx, memc_list_t* memc_list) | ||||
| { | ||||
| 	memc_node_t* memc_node; | ||||
|  | ||||
| 	memc_node = __new_memc_node(rtx, memc_list); | ||||
| 	if (!memc_node) return HAWK_NULL; | ||||
|  | ||||
| 	memc_node->memc = HAWK_NULL; | ||||
| 	return memc_node; | ||||
| } | ||||
|  | ||||
| static void free_memc_node (hawk_rtx_t* rtx, memc_list_t* memc_list, memc_node_t* memc_node) | ||||
| { | ||||
| 	if (memc_node->memc != HAWK_NULL) { | ||||
| 		memcached_free (memc_node->memc); | ||||
| 		memc_node->memc = HAWK_NULL; | ||||
| 	} | ||||
|  | ||||
| 	__free_memc_node (rtx, memc_list, memc_node); | ||||
| } | ||||
|  | ||||
| static HAWK_INLINE memc_list_t* rtx_to_memc_list (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	hawk_rbt_pair_t* pair; | ||||
| 	rtx_data_t* data; | ||||
|  | ||||
| 	pair = hawk_rbt_search((hawk_rbt_t*)fi->mod->ctx, &rtx, HAWK_SIZEOF(rtx)); | ||||
| 	HAWK_ASSERT (pair != HAWK_NULL); | ||||
| 	data = (rtx_data_t*)HAWK_RBT_VPTR(pair); | ||||
| 	return &data->memc_list; | ||||
| } | ||||
|  | ||||
| static void set_error_on_memc_list (hawk_rtx_t* rtx, memc_list_t* memc_list, const hawk_ooch_t* errfmt, ...) | ||||
| { | ||||
| 	if (errfmt) | ||||
| 	{ | ||||
| 		va_list ap; | ||||
| 		va_start (ap, errfmt); | ||||
| 		hawk_rtx_vfmttooocstr (rtx, memc_list->errmsg, HAWK_COUNTOF(memc_list->errmsg), errfmt, ap); | ||||
| 		va_end (ap); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		hawk_copy_oocstr (memc_list->errmsg, HAWK_COUNTOF(memc_list->errmsg), hawk_rtx_geterrmsg(rtx)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static HAWK_INLINE memc_node_t* get_memc_list_node (memc_list_t* memc_list, hawk_int_t id) | ||||
| { | ||||
| 	if (id < 0 || id >= memc_list->map.high || !memc_list->map.tab[id]) return HAWK_NULL; | ||||
| 	return memc_list->map.tab[id]; | ||||
| } | ||||
|  | ||||
| static memc_node_t* get_memc_list_node_with_arg (hawk_rtx_t* rtx, memc_list_t* memc_list, hawk_val_t* arg) | ||||
| { | ||||
| 	hawk_int_t id; | ||||
| 	memc_node_t* memc_node; | ||||
|  | ||||
| 	if (hawk_rtx_valtoint(rtx, arg, &id) <= -1) | ||||
| 	{ | ||||
| 		set_error_on_memc_list (rtx, memc_list, HAWK_T("illegal instance id")); | ||||
| 		return HAWK_NULL; | ||||
| 	} | ||||
| 	else if (!(memc_node = get_memc_list_node(memc_list, id))) | ||||
| 	{ | ||||
| 		set_error_on_memc_list (rtx, memc_list, HAWK_T("invalid instance id - %zd"), (hawk_oow_t)id); | ||||
| 		return HAWK_NULL; | ||||
| 	} | ||||
|  | ||||
| 	return memc_node; | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| static int fnc_new (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	memc_list_t* memc_list; | ||||
| 	memc_node_t* memc_node = HAWK_NULL; | ||||
| 	hawk_int_t ret = -1; | ||||
| 	hawk_val_t* retv; | ||||
|  | ||||
| 	memc_list = rtx_to_memc_list(rtx, fi); | ||||
|  | ||||
| 	memc_node = new_memc_node(rtx, memc_list); | ||||
| 	if (memc_node) ret = memc_node->id; | ||||
| 	else set_error_on_memc_list (rtx, memc_list, HAWK_NULL); | ||||
|  | ||||
| 	/* ret may not be a statically managed number. | ||||
| 	 * error checking is required */ | ||||
| 	retv = hawk_rtx_makeintval(rtx, ret); | ||||
| 	if (retv == HAWK_NULL) | ||||
| 	{ | ||||
| 		if (memc_node) free_memc_node (rtx, memc_list, memc_node); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	hawk_rtx_setretval (rtx, retv); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int fnc_connect (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	memc_list_t* memc_list; | ||||
| 	memc_node_t* memc_node; | ||||
| 	hawk_val_t* a0; | ||||
| 	hawk_bch_t* conf = HAWK_NULL; | ||||
| 	hawk_oow_t conf_len = 0; | ||||
| 	int ret = -1, take_rtx_err = 0; | ||||
|  | ||||
| 	memc_list = rtx_to_memc_list(rtx, fi); | ||||
| 	memc_node = get_memc_list_node_with_arg(rtx, memc_list, hawk_rtx_getarg(rtx, 0)); | ||||
| 	if (memc_node) | ||||
| 	{ | ||||
| 		a0 = hawk_rtx_getarg(rtx, 0); | ||||
| 		if (!(conf = hawk_rtx_getvalbcstr(rtx, a0, &conf_len))) | ||||
| 		{ | ||||
| 			take_rtx_err = 1; | ||||
| 			goto done; | ||||
| 		} | ||||
|  | ||||
| 		memc_node->memc = memcached (conf, conf_len); | ||||
| 		if (memc_node->memc == HAWK_NULL) | ||||
| 		{ | ||||
| 			set_error_on_memc_list (rtx, memc_list, HAWK_T("unable to connect to %hs"), conf); | ||||
| 			goto done; | ||||
| 		} | ||||
|  | ||||
| 		ret = 0; | ||||
| 	} | ||||
|  | ||||
| done: | ||||
| 	if (take_rtx_err) set_error_on_memc_list (rtx, memc_list, HAWK_NULL); | ||||
| 	if (conf) hawk_rtx_freevalbcstr (rtx, a0, conf); | ||||
|  | ||||
| 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ret)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int fnc_close (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	memc_list_t* memc_list; | ||||
| 	memc_node_t* memc_node; | ||||
| 	int ret = -1; | ||||
|  | ||||
| 	memc_list = rtx_to_memc_list(rtx, fi); | ||||
| 	memc_node = get_memc_list_node_with_arg(rtx, memc_list, hawk_rtx_getarg(rtx, 0)); | ||||
| 	if (memc_node) | ||||
| 	{ | ||||
| 		free_memc_node (rtx, memc_list, memc_node); | ||||
| 		ret = 0; | ||||
| 	} | ||||
|  | ||||
| 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ret)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int fnc_errmsg (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	memc_list_t* memc_list; | ||||
| 	hawk_val_t* retv; | ||||
|  | ||||
| 	memc_list = rtx_to_memc_list(rtx, fi); | ||||
| 	retv = hawk_rtx_makestrvalwithoocstr(rtx, memc_list->errmsg); | ||||
| 	if (!retv) return -1; | ||||
|  | ||||
| 	hawk_rtx_setretval (rtx, retv); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int fnc_get (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	memc_list_t* memc_list; | ||||
| 	memc_node_t* memc_node; | ||||
| 	int take_rtx_err = 0; | ||||
|  | ||||
| 	hawk_val_t* a1, * a2; | ||||
| 	hawk_bch_t* key = HAWK_NULL; | ||||
| 	hawk_bch_t* def_val = HAWK_NULL; | ||||
| 	hawk_bch_t* rv = HAWK_NULL; | ||||
| 	hawk_oow_t key_len = 0; | ||||
| 	hawk_oow_t def_val_len = 0; | ||||
| 	hawk_oow_t rv_len = 0; | ||||
| 	char* val = HAWK_NULL; | ||||
| 	size_t val_len = 0; | ||||
|  | ||||
| 	memc_list = rtx_to_memc_list(rtx, fi); | ||||
| 	memc_node = get_memc_list_node_with_arg(rtx, memc_list, hawk_rtx_getarg(rtx, 0)); | ||||
| 	if (!memc_node) | ||||
| 	{ | ||||
| 		goto done; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		uint32_t flags; | ||||
| 		memcached_return_t rc; | ||||
|  | ||||
| 		hawk_oow_t nargs; | ||||
| 		nargs = hawk_rtx_getnargs(rtx); | ||||
|  | ||||
| 		a1 = hawk_rtx_getarg(rtx, 1); | ||||
| 		if (!(key = hawk_rtx_getvalbcstr(rtx, a1, &key_len))) | ||||
| 		{ | ||||
| 			take_rtx_err = 1; | ||||
| 			goto done; | ||||
| 		} | ||||
|  | ||||
| 		if (nargs >= 3) | ||||
| 		{ | ||||
| 			a2 = hawk_rtx_getarg(rtx, 2); | ||||
| 			if (!(def_val = hawk_rtx_getvalbcstr(rtx, a2, &def_val_len))) | ||||
| 			{ | ||||
| 				take_rtx_err = 1; | ||||
| 				goto done; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		val = memcached_get(memc_node->memc, key, key_len, &val_len, &flags, &rc); | ||||
| 		if (val == HAWK_NULL) goto done; | ||||
|  | ||||
| 		rv = val; | ||||
| 		rv_len = val_len; | ||||
| 	} | ||||
|  | ||||
| done: | ||||
| 	if (rv == HAWK_NULL) | ||||
| 	{ | ||||
| 		if (def_val != HAWK_NULL) rv = ""; | ||||
| 		else | ||||
| 		{ | ||||
| 			rv = def_val; | ||||
| 			rv_len = def_val_len; | ||||
| 		} | ||||
| 	} | ||||
| 	hawk_rtx_setretval (rtx, hawk_rtx_makestrvalwithbchars(rtx, rv, rv_len)); | ||||
|  | ||||
| 	if (take_rtx_err) set_error_on_memc_list (rtx, memc_list, HAWK_NULL); | ||||
| 	if (key) hawk_rtx_freevalbcstr (rtx, a1, key); | ||||
| 	if (def_val) hawk_rtx_freevalbcstr (rtx, a2, def_val); | ||||
| 	if (val) free(val); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int fnc_set (hawk_rtx_t* rtx, const hawk_fnc_info_t* fi) | ||||
| { | ||||
| 	memc_list_t* memc_list; | ||||
| 	memc_node_t* memc_node; | ||||
| 	int ret = -1; | ||||
| 	int take_rtx_err = 0; | ||||
|  | ||||
| 	hawk_val_t* a1, * a2, * a3, * a4; | ||||
| 	hawk_bch_t* key = HAWK_NULL; | ||||
| 	hawk_bch_t* val = HAWK_NULL; | ||||
| 	hawk_oow_t key_len = 0; | ||||
| 	hawk_oow_t val_len = 0; | ||||
| 	hawk_int_t ttl = 0; | ||||
| 	hawk_int_t flag = 0; | ||||
|  | ||||
| 	memc_list = rtx_to_memc_list(rtx, fi); | ||||
| 	memc_node = get_memc_list_node_with_arg(rtx, memc_list, hawk_rtx_getarg(rtx, 0)); | ||||
| 	if (!memc_node) | ||||
| 	{ | ||||
| 		goto done; | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		hawk_oow_t nargs; | ||||
| 		memcached_return_t rc; | ||||
|  | ||||
| 		a1 = hawk_rtx_getarg(rtx, 1); | ||||
| 		a2 = hawk_rtx_getarg(rtx, 2); | ||||
| 		a3 = hawk_rtx_getarg(rtx, 3); | ||||
|  | ||||
| 		if (!(key = hawk_rtx_getvalbcstr(rtx, a1, &key_len)) || | ||||
| 		    !(val = hawk_rtx_getvalbcstr(rtx, a2, &val_len)) || | ||||
| 		    (hawk_rtx_valtoint(rtx, a3, &ttl) <= -1)) | ||||
| 		{ | ||||
| 			take_rtx_err = 1; | ||||
| 			goto done; | ||||
| 		} | ||||
|  | ||||
| 		nargs = hawk_rtx_getnargs(rtx); | ||||
| 		if (nargs >= 5) { | ||||
| 			a4 = hawk_rtx_getarg(rtx, 4); | ||||
| 			if (hawk_rtx_valtoint(rtx, a4, &flag) <= -1) | ||||
| 			{ | ||||
| 				take_rtx_err = 1; | ||||
| 				goto done; | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		rc = memcached_set(memc_node->memc, key, key_len, val, val_len, ttl, flag); | ||||
| 		if (rc != MEMCACHED_SUCCESS) { | ||||
| 			goto done; | ||||
| 		} | ||||
|  | ||||
| 		ret = 0; | ||||
| 	} | ||||
|  | ||||
| done: | ||||
| 	if (take_rtx_err) set_error_on_memc_list (rtx, memc_list, HAWK_NULL); | ||||
| 	if (key) hawk_rtx_freevalbcstr (rtx, a1, key); | ||||
| 	if (val) hawk_rtx_freevalbcstr (rtx, a2, val); | ||||
|  | ||||
| 	hawk_rtx_setretval (rtx, hawk_rtx_makeintval(rtx, ret)); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
|  | ||||
| static hawk_mod_fnc_tab_t fnctab[] = | ||||
| { | ||||
| 	/* keep this table sorted for binary search in query(). */ | ||||
| 	{ HAWK_T("close"),   { { 1, 1, HAWK_NULL }, fnc_close,   0 } }, | ||||
| 	{ HAWK_T("connect"), { { 1, 1, HAWK_NULL }, fnc_connect, 0 } }, | ||||
| 	{ HAWK_T("errmsg"),  { { 0, 0, HAWK_NULL }, fnc_errmsg,  0 } }, | ||||
| 	{ HAWK_T("get"),     { { 2, 3, HAWK_NULL }, fnc_get,     0 } }, | ||||
| 	{ HAWK_T("new"),     { { 0, 0, HAWK_NULL }, fnc_new,     0 } }, | ||||
| 	{ HAWK_T("set"),     { { 4, 5, HAWK_NULL }, fnc_set,     0 } }, | ||||
| }; | ||||
|  | ||||
| static int query (hawk_mod_t* mod, hawk_t* hawk, const hawk_ooch_t* name, hawk_mod_sym_t* sym) | ||||
| { | ||||
| 	return hawk_findmodsymfnc(hawk, fnctab, HAWK_COUNTOF(fnctab), name, sym); | ||||
| } | ||||
|  | ||||
| static int init (hawk_mod_t* mod, hawk_rtx_t* rtx) | ||||
| { | ||||
| 	hawk_rbt_t* rbt; | ||||
| 	rtx_data_t data, * datap; | ||||
| 	hawk_rbt_pair_t* pair; | ||||
|  | ||||
| 	rbt = (hawk_rbt_t*)mod->ctx; | ||||
|  | ||||
| 	HAWK_MEMSET (&data, 0, HAWK_SIZEOF(data)); | ||||
| 	pair = hawk_rbt_insert(rbt, &rtx, HAWK_SIZEOF(rtx), &data, HAWK_SIZEOF(data)); | ||||
| 	if (HAWK_UNLIKELY(!pair)) return -1; | ||||
|  | ||||
| 	datap = (rtx_data_t*)HAWK_RBT_VPTR(pair); | ||||
| 	__init_memc_list (rtx, &datap->memc_list); | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static void fini (hawk_mod_t* mod, hawk_rtx_t* rtx) | ||||
| { | ||||
| 	hawk_rbt_t* rbt; | ||||
| 	hawk_rbt_pair_t* pair; | ||||
|  | ||||
| 	rbt = (hawk_rbt_t*)mod->ctx; | ||||
|  | ||||
| 	/* garbage clean-up */ | ||||
| 	pair = hawk_rbt_search(rbt, &rtx, HAWK_SIZEOF(rtx)); | ||||
| 	if (pair) | ||||
| 	{ | ||||
| 		rtx_data_t* data; | ||||
|  | ||||
| 		data = (rtx_data_t*)HAWK_RBT_VPTR(pair); | ||||
| 		__fini_memc_list (rtx, &data->memc_list); | ||||
| 		hawk_rbt_delete (rbt, &rtx, HAWK_SIZEOF(rtx)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void unload (hawk_mod_t* mod, hawk_t* hawk) | ||||
| { | ||||
| 	hawk_rbt_t* rbt; | ||||
|  | ||||
| 	rbt = (hawk_rbt_t*)mod->ctx; | ||||
|  | ||||
| 	HAWK_ASSERT (HAWK_RBT_SIZE(rbt) == 0); | ||||
| 	hawk_rbt_close (rbt); | ||||
| } | ||||
|  | ||||
| int hawk_mod_memc (hawk_mod_t* mod, hawk_t* hawk) | ||||
| { | ||||
| 	hawk_rbt_t* rbt; | ||||
|  | ||||
| 	mod->query = query; | ||||
| 	mod->unload = unload; | ||||
|  | ||||
| 	mod->init = init; | ||||
| 	mod->fini = fini; | ||||
|  | ||||
| 	rbt = hawk_rbt_open(hawk_getgem(hawk), 0, 1, 1); | ||||
| 	if (HAWK_UNLIKELY(!rbt)) return -1; | ||||
|  | ||||
| 	hawk_rbt_setstyle (rbt, hawk_get_rbt_style(HAWK_RBT_STYLE_INLINE_COPIERS)); | ||||
| 	mod->ctx = rbt; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* ------------------------------------------------------------------------ */ | ||||
| /* | ||||
| BEGIN { | ||||
| 	conn = memc::new(); | ||||
| 	if (memc::connect("--SERVER=localhost") <= -1) | ||||
| 	{ | ||||
| 		print "connect error -", memc::errmsg(); | ||||
|         return -1; | ||||
| 	} | ||||
|  | ||||
| 	rc = memc::set(conn, "key", "val", 900); | ||||
| 	if (rc <= -1) { | ||||
| 		print "store result error - ", memc::errmsg(); | ||||
| 	} | ||||
|  | ||||
| 	val = memc::get(conn, "key");            print val; | ||||
| 	val = memc::get(conn, "key", "default"); print val; | ||||
|  | ||||
| 	memc::close(conn); | ||||
| } | ||||
| */ | ||||
							
								
								
									
										43
									
								
								mod/mod-memc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								mod/mod-memc.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| /* | ||||
|  * $Id$ | ||||
|  * | ||||
|     Copyright (c) 2006-2020 Chung, Hyung-Hwan. All rights reserved. | ||||
|  | ||||
|     Redistribution and use in source and binary forms, with or without | ||||
|     modification, are permitted provided that the following conditions | ||||
|     are met: | ||||
|     1. Redistributions of source code must retain the above copyright | ||||
|        notice, this list of conditions and the following disclaimer. | ||||
|     2. Redistributions in binary form must reproduce the above copyright | ||||
|        notice, this list of conditions and the following disclaimer in the | ||||
|        documentation and/or other materials provided with the distribution. | ||||
|  | ||||
|     THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR | ||||
|     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||||
|     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||||
|     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||
|     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||||
|     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
|     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
|     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
|     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||||
|     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
|  | ||||
| #ifndef _HAWK_MOD_MEMC_H_ | ||||
| #define _HAWK_MOD_MEMC_H_ | ||||
|  | ||||
| #include <hawk.h> | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| HAWK_EXPORT int hawk_mod_memc (hawk_mod_t* mod, hawk_t* hawk); | ||||
|  | ||||
| #if defined(__cplusplus) | ||||
| } | ||||
| #endif | ||||
|  | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user