aboutsummaryrefslogtreecommitdiff
path: root/src/lockmanager
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockmanager')
-rw-r--r--src/lockmanager/Makefile.am68
-rw-r--r--src/lockmanager/Makefile.in933
-rw-r--r--src/lockmanager/gnunet-service-lockmanager.c899
-rw-r--r--src/lockmanager/lockmanager.conf.in13
-rw-r--r--src/lockmanager/lockmanager.h71
-rw-r--r--src/lockmanager/lockmanager_api.c677
-rw-r--r--src/lockmanager/test_lockmanager_api.c279
-rw-r--r--src/lockmanager/test_lockmanager_api.conf73
-rw-r--r--src/lockmanager/test_lockmanager_api_lockrelease.c301
-rw-r--r--src/lockmanager/test_lockmanager_api_servercrash.c326
10 files changed, 3640 insertions, 0 deletions
diff --git a/src/lockmanager/Makefile.am b/src/lockmanager/Makefile.am
new file mode 100644
index 0000000..0fbc20b
--- /dev/null
+++ b/src/lockmanager/Makefile.am
@@ -0,0 +1,68 @@
+INCLUDES = -I$(top_srcdir)/src/include
+
+if MINGW
+ WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
+endif
+
+if USE_COVERAGE
+ AM_CFLAGS = --coverage -O0
+ XLIB = -lgcov
+endif
+
+pkgcfgdir= $(pkgdatadir)/config.d/
+
+pkgcfg_DATA = \
+ lockmanager.conf
+
+bin_PROGRAMS = \
+ gnunet-service-lockmanager
+
+lib_LTLIBRARIES = \
+ libgnunetlockmanager.la
+
+gnunet_service_lockmanager_SOURCES = \
+ gnunet-service-lockmanager.c \
+ lockmanager.h
+gnunet_service_lockmanager_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+gnunet_service_lockmanager_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+libgnunetlockmanager_la_SOURCES = \
+ lockmanager_api.c lockmanager.h
+libgnunetlockmanager_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(XLIB)
+libgnunetlockmanager_la_LDFLAGS = \
+ $(GN_LIB_LDFLAGS) $(WINFLAGS) \
+ -version-info 0:0:0
+
+check_PROGRAMS = \
+ test-lockmanager-api \
+ test-lockmanager-api-lockrelease \
+ test-lockmanager-api-servercrash
+
+EXTRA_DIST = \
+ test_lockmanager_api.conf
+
+if ENABLE_TEST_RUN
+TESTS = $(check_PROGRAMS)
+endif
+
+test_lockmanager_api_SOURCES = \
+ test_lockmanager_api.c
+test_lockmanager_api_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+
+test_lockmanager_api_lockrelease_SOURCES = \
+ test_lockmanager_api_lockrelease.c
+test_lockmanager_api_lockrelease_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+
+test_lockmanager_api_servercrash_SOURCES = \
+ test_lockmanager_api_servercrash.c
+test_lockmanager_api_servercrash_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la \ No newline at end of file
diff --git a/src/lockmanager/Makefile.in b/src/lockmanager/Makefile.in
new file mode 100644
index 0000000..6a90407
--- /dev/null
+++ b/src/lockmanager/Makefile.in
@@ -0,0 +1,933 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+bin_PROGRAMS = gnunet-service-lockmanager$(EXEEXT)
+check_PROGRAMS = test-lockmanager-api$(EXEEXT) \
+ test-lockmanager-api-lockrelease$(EXEEXT) \
+ test-lockmanager-api-servercrash$(EXEEXT)
+subdir = src/lockmanager
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(srcdir)/lockmanager.conf.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/m4/absolute-header.m4 \
+ $(top_srcdir)/m4/align.m4 $(top_srcdir)/m4/argz.m4 \
+ $(top_srcdir)/m4/gettext.m4 $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
+ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libcurl.m4 \
+ $(top_srcdir)/m4/libgcrypt.m4 $(top_srcdir)/m4/libtool.m4 \
+ $(top_srcdir)/m4/libunistring.m4 $(top_srcdir)/m4/ltdl.m4 \
+ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
+ $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
+ $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
+ $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/gnunet_config.h
+CONFIG_CLEAN_FILES = lockmanager.conf
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+ "$(DESTDIR)$(pkgcfgdir)"
+LTLIBRARIES = $(lib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libgnunetlockmanager_la_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(am__DEPENDENCIES_1)
+am_libgnunetlockmanager_la_OBJECTS = lockmanager_api.lo
+libgnunetlockmanager_la_OBJECTS = \
+ $(am_libgnunetlockmanager_la_OBJECTS)
+AM_V_lt = $(am__v_lt_$(V))
+am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
+am__v_lt_0 = --silent
+libgnunetlockmanager_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+ $(AM_CFLAGS) $(CFLAGS) $(libgnunetlockmanager_la_LDFLAGS) \
+ $(LDFLAGS) -o $@
+PROGRAMS = $(bin_PROGRAMS)
+am_gnunet_service_lockmanager_OBJECTS = \
+ gnunet-service-lockmanager.$(OBJEXT)
+gnunet_service_lockmanager_OBJECTS = \
+ $(am_gnunet_service_lockmanager_OBJECTS)
+am_test_lockmanager_api_OBJECTS = test_lockmanager_api.$(OBJEXT)
+test_lockmanager_api_OBJECTS = $(am_test_lockmanager_api_OBJECTS)
+test_lockmanager_api_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+am_test_lockmanager_api_lockrelease_OBJECTS = \
+ test_lockmanager_api_lockrelease.$(OBJEXT)
+test_lockmanager_api_lockrelease_OBJECTS = \
+ $(am_test_lockmanager_api_lockrelease_OBJECTS)
+test_lockmanager_api_lockrelease_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+am_test_lockmanager_api_servercrash_OBJECTS = \
+ test_lockmanager_api_servercrash.$(OBJEXT)
+test_lockmanager_api_servercrash_OBJECTS = \
+ $(am_test_lockmanager_api_servercrash_OBJECTS)
+test_lockmanager_api_servercrash_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+ $(AM_CFLAGS) $(CFLAGS)
+AM_V_CC = $(am__v_CC_$(V))
+am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
+am__v_CC_0 = @echo " CC " $@;
+AM_V_at = $(am__v_at_$(V))
+am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
+am__v_at_0 = @
+CCLD = $(CC)
+LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(AM_LDFLAGS) $(LDFLAGS) -o $@
+AM_V_CCLD = $(am__v_CCLD_$(V))
+am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
+am__v_CCLD_0 = @echo " CCLD " $@;
+AM_V_GEN = $(am__v_GEN_$(V))
+am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
+am__v_GEN_0 = @echo " GEN " $@;
+SOURCES = $(libgnunetlockmanager_la_SOURCES) \
+ $(gnunet_service_lockmanager_SOURCES) \
+ $(test_lockmanager_api_SOURCES) \
+ $(test_lockmanager_api_lockrelease_SOURCES) \
+ $(test_lockmanager_api_servercrash_SOURCES)
+DIST_SOURCES = $(libgnunetlockmanager_la_SOURCES) \
+ $(gnunet_service_lockmanager_SOURCES) \
+ $(test_lockmanager_api_SOURCES) \
+ $(test_lockmanager_api_lockrelease_SOURCES) \
+ $(test_lockmanager_api_servercrash_SOURCES)
+DATA = $(pkgcfg_DATA)
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
+AR = @AR@
+ARGZ_H = @ARGZ_H@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFAULT_INTERFACE = @DEFAULT_INTERFACE@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DLLDIR = @DLLDIR@
+DLLTOOL = @DLLTOOL@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+EXT_LIBS = @EXT_LIBS@
+EXT_LIB_PATH = @EXT_LIB_PATH@
+FGREP = @FGREP@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GNUNETDNS_GROUP = @GNUNETDNS_GROUP@
+GN_DAEMON_CONFIG_DIR = @GN_DAEMON_CONFIG_DIR@
+GN_DAEMON_HOME_DIR = @GN_DAEMON_HOME_DIR@
+GN_INTLINCL = @GN_INTLINCL@
+GN_LIBINTL = @GN_LIBINTL@
+GN_LIB_LDFLAGS = @GN_LIB_LDFLAGS@
+GN_PLUGIN_LDFLAGS = @GN_PLUGIN_LDFLAGS@
+GN_USER_HOME_DIR = @GN_USER_HOME_DIR@
+GREP = @GREP@
+HAVE_LIBUNISTRING = @HAVE_LIBUNISTRING@
+INCLTDL = @INCLTDL@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+JAVAPORT = @JAVAPORT@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBADD_DL = @LIBADD_DL@
+LIBADD_DLD_LINK = @LIBADD_DLD_LINK@
+LIBADD_DLOPEN = @LIBADD_DLOPEN@
+LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@
+LIBCURL = @LIBCURL@
+LIBCURL_CPPFLAGS = @LIBCURL_CPPFLAGS@
+LIBGCRYPT_CFLAGS = @LIBGCRYPT_CFLAGS@
+LIBGCRYPT_CONFIG = @LIBGCRYPT_CONFIG@
+LIBGCRYPT_LIBS = @LIBGCRYPT_LIBS@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBLTDL = @LIBLTDL@
+LIBOBJS = @LIBOBJS@
+LIBPREFIX = @LIBPREFIX@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIBUNISTRING = @LIBUNISTRING@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTDLDEPS = @LTDLDEPS@
+LTDLINCL = @LTDLINCL@
+LTDLOPEN = @LTDLOPEN@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+LTLIBUNISTRING = @LTLIBUNISTRING@
+LT_CONFIG_H = @LT_CONFIG_H@
+LT_DLLOADERS = @LT_DLLOADERS@
+LT_DLPREOPEN = @LT_DLPREOPEN@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MONKEYPREFIX = @MONKEYPREFIX@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+MYSQL_CPPFLAGS = @MYSQL_CPPFLAGS@
+MYSQL_LDFLAGS = @MYSQL_LDFLAGS@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJC = @OBJC@
+OBJCDEPMODE = @OBJCDEPMODE@
+OBJCFLAGS = @OBJCFLAGS@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+POSTGRES_CPPFLAGS = @POSTGRES_CPPFLAGS@
+POSTGRES_LDFLAGS = @POSTGRES_LDFLAGS@
+POSUB = @POSUB@
+PYTHON = @PYTHON@
+PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
+PYTHON_PLATFORM = @PYTHON_PLATFORM@
+PYTHON_PREFIX = @PYTHON_PREFIX@
+PYTHON_VERSION = @PYTHON_VERSION@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SQLITE_CPPFLAGS = @SQLITE_CPPFLAGS@
+SQLITE_LDFLAGS = @SQLITE_LDFLAGS@
+STRIP = @STRIP@
+SUDO_BINARY = @SUDO_BINARY@
+UNIXONLY = @UNIXONLY@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+_libcurl_config = @_libcurl_config@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+ac_ct_OBJC = @ac_ct_OBJC@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_target = @build_target@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+ltdl_LIBOBJS = @ltdl_LIBOBJS@
+ltdl_LTLIBOBJS = @ltdl_LTLIBOBJS@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+pkgpyexecdir = @pkgpyexecdir@
+pkgpythondir = @pkgpythondir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+pyexecdir = @pyexecdir@
+pythondir = @pythondir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+subdirs = @subdirs@
+sys_symbol_underscore = @sys_symbol_underscore@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_os = @target_os@
+target_vendor = @target_vendor@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+INCLUDES = -I$(top_srcdir)/src/include
+@MINGW_TRUE@WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
+@USE_COVERAGE_TRUE@AM_CFLAGS = --coverage -O0
+@USE_COVERAGE_TRUE@XLIB = -lgcov
+pkgcfgdir = $(pkgdatadir)/config.d/
+pkgcfg_DATA = \
+ lockmanager.conf
+
+lib_LTLIBRARIES = \
+ libgnunetlockmanager.la
+
+gnunet_service_lockmanager_SOURCES = \
+ gnunet-service-lockmanager.c \
+ lockmanager.h
+
+gnunet_service_lockmanager_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+gnunet_service_lockmanager_DEPENDENCIES = \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+libgnunetlockmanager_la_SOURCES = \
+ lockmanager_api.c lockmanager.h
+
+libgnunetlockmanager_la_LIBADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ $(XLIB)
+
+libgnunetlockmanager_la_LDFLAGS = \
+ $(GN_LIB_LDFLAGS) $(WINFLAGS) \
+ -version-info 0:0:0
+
+EXTRA_DIST = \
+ test_lockmanager_api.conf
+
+@ENABLE_TEST_RUN_TRUE@TESTS = $(check_PROGRAMS)
+test_lockmanager_api_SOURCES = \
+ test_lockmanager_api.c
+
+test_lockmanager_api_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+
+test_lockmanager_api_lockrelease_SOURCES = \
+ test_lockmanager_api_lockrelease.c
+
+test_lockmanager_api_lockrelease_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+
+test_lockmanager_api_servercrash_SOURCES = \
+ test_lockmanager_api_servercrash.c
+
+test_lockmanager_api_servercrash_LDADD = \
+ $(top_builddir)/src/util/libgnunetutil.la \
+ libgnunetlockmanager.la
+
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/lockmanager/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --gnu src/lockmanager/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+lockmanager.conf: $(top_builddir)/config.status $(srcdir)/lockmanager.conf.in
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+ }
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+ done
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libgnunetlockmanager.la: $(libgnunetlockmanager_la_OBJECTS) $(libgnunetlockmanager_la_DEPENDENCIES)
+ $(AM_V_CCLD)$(libgnunetlockmanager_la_LINK) -rpath $(libdir) $(libgnunetlockmanager_la_OBJECTS) $(libgnunetlockmanager_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed 's/$(EXEEXT)$$//' | \
+ while read p p1; do if test -f $$p || test -f $$p1; \
+ then echo "$$p"; echo "$$p"; else :; fi; \
+ done | \
+ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+ sed 'N;N;N;s,\n, ,g' | \
+ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+ if ($$2 == $$4) files[d] = files[d] " " $$1; \
+ else { print "f", $$3 "/" $$4, $$1; } } \
+ END { for (d in files) print "f", d, files[d] }' | \
+ while read type dir files; do \
+ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+ test -z "$$files" || { \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+ } \
+ ; done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+ files=`for p in $$list; do echo "$$p"; done | \
+ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+ -e 's/$$/$(EXEEXT)/' `; \
+ test -n "$$list" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+
+clean-checkPROGRAMS:
+ @list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+ echo " rm -f" $$list; \
+ rm -f $$list || exit $$?; \
+ test -n "$(EXEEXT)" || exit 0; \
+ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f" $$list; \
+ rm -f $$list
+gnunet-service-lockmanager$(EXEEXT): $(gnunet_service_lockmanager_OBJECTS) $(gnunet_service_lockmanager_DEPENDENCIES)
+ @rm -f gnunet-service-lockmanager$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(gnunet_service_lockmanager_OBJECTS) $(gnunet_service_lockmanager_LDADD) $(LIBS)
+test-lockmanager-api$(EXEEXT): $(test_lockmanager_api_OBJECTS) $(test_lockmanager_api_DEPENDENCIES)
+ @rm -f test-lockmanager-api$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_lockmanager_api_OBJECTS) $(test_lockmanager_api_LDADD) $(LIBS)
+test-lockmanager-api-lockrelease$(EXEEXT): $(test_lockmanager_api_lockrelease_OBJECTS) $(test_lockmanager_api_lockrelease_DEPENDENCIES)
+ @rm -f test-lockmanager-api-lockrelease$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_lockmanager_api_lockrelease_OBJECTS) $(test_lockmanager_api_lockrelease_LDADD) $(LIBS)
+test-lockmanager-api-servercrash$(EXEEXT): $(test_lockmanager_api_servercrash_OBJECTS) $(test_lockmanager_api_servercrash_DEPENDENCIES)
+ @rm -f test-lockmanager-api-servercrash$(EXEEXT)
+ $(AM_V_CCLD)$(LINK) $(test_lockmanager_api_servercrash_OBJECTS) $(test_lockmanager_api_servercrash_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gnunet-service-lockmanager.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockmanager_api.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lockmanager_api.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lockmanager_api_lockrelease.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_lockmanager_api_servercrash.Po@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-pkgcfgDATA: $(pkgcfg_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(pkgcfgdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgcfgdir)"
+ @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgcfgdir)'"; \
+ $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgcfgdir)" || exit $$?; \
+ done
+
+uninstall-pkgcfgDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(pkgcfg_DATA)'; test -n "$(pkgcfgdir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(pkgcfgdir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(pkgcfgdir)" && rm -f $$files
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ $(am__tty_colors); \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=XPASS; \
+ ;; \
+ *) \
+ col=$$grn; res=PASS; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *[\ \ ]$$tst[\ \ ]*) \
+ xfail=`expr $$xfail + 1`; \
+ col=$$lgn; res=XFAIL; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ col=$$red; res=FAIL; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ col=$$blu; res=SKIP; \
+ fi; \
+ echo "$${col}$$res$${std}: $$tst"; \
+ done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="$$All$$all $$tests passed"; \
+ else \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all $$tests failed"; \
+ else \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+ fi; \
+ fi; \
+ dashes="$$banner"; \
+ skipped=""; \
+ if test "$$skip" -ne 0; then \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ if test "$$failed" -eq 0; then \
+ echo "$$grn$$dashes"; \
+ else \
+ echo "$$red$$dashes"; \
+ fi; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes$$std"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d "$(distdir)/$$file"; then \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+ fi; \
+ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+ else \
+ test -f "$(distdir)/$$file" \
+ || cp -p $$d/$$file "$(distdir)/$$file" \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA)
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs:
+ for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(pkgcfgdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am: install-pkgcfgDATA
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+ uninstall-pkgcfgDATA
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-binPROGRAMS clean-checkPROGRAMS clean-generic \
+ clean-libLTLIBRARIES clean-libtool ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags distdir dvi dvi-am html html-am info info-am \
+ install install-am install-binPROGRAMS install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-libLTLIBRARIES install-man install-pdf \
+ install-pdf-am install-pkgcfgDATA install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ pdf pdf-am ps ps-am tags uninstall uninstall-am \
+ uninstall-binPROGRAMS uninstall-libLTLIBRARIES \
+ uninstall-pkgcfgDATA
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/lockmanager/gnunet-service-lockmanager.c b/src/lockmanager/gnunet-service-lockmanager.c
new file mode 100644
index 0000000..8ec9889
--- /dev/null
+++ b/src/lockmanager/gnunet-service-lockmanager.c
@@ -0,0 +1,899 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file lockmanager/gnunet-service-lockmanager.c
+ * @brief implementation of the LOCKMANAGER service
+ * @author Sree Harsha Totakura
+ */
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_container_lib.h"
+#include "gnunet_protocols.h"
+#include "gnunet_service_lib.h"
+#include "gnunet_server_lib.h"
+
+#include "lockmanager.h"
+
+
+#define LOG(kind,...) \
+ GNUNET_log (kind, __VA_ARGS__)
+
+#define TIME_REL_MINS(min) \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min)
+
+#define TIMEOUT TIME_REL_MINS(3)
+
+
+/**
+ * Doubly linked list of clients having connections to us
+ */
+struct ClientList;
+
+
+/**
+ * Doubly linked list of clients waiting for a lock
+ */
+struct WaitList
+{
+ /**
+ * The next client structure
+ */
+ struct WaitList *next;
+
+ /**
+ * The prev client structure
+ */
+ struct WaitList *prev;
+
+ /**
+ * Pointer to the client
+ */
+ struct ClientList *cl_entry;
+};
+
+
+/**
+ * Structure representing a Lock
+ */
+struct Lock
+{
+ /**
+ * List head of clients waiting for this lock
+ */
+ struct WaitList *wl_head;
+
+ /**
+ * List tail of clients waiting for this lock
+ */
+ struct WaitList *wl_tail;
+
+ /**
+ * The client which is currently holding this lock
+ */
+ struct ClientList *cl_entry;
+
+ /**
+ * The name of the locking domain this lock belongs to
+ */
+ char *domain_name;
+
+ /**
+ * The number of this lock
+ */
+ uint32_t lock_num;
+};
+
+
+/**
+ * A Lock element for a doubly linked list
+ */
+struct LockList
+{
+ /**
+ * The next element pointer
+ */
+ struct LockList *next;
+
+ /**
+ * Pointer to the previous element
+ */
+ struct LockList *prev;
+
+ /**
+ * Pointer to the Lock
+ */
+ struct Lock *lock;
+};
+
+
+/**
+ * Doubly linked list of clients having connections to us
+ */
+struct ClientList
+{
+
+ /**
+ * The next client structure
+ */
+ struct ClientList *next;
+
+ /**
+ * The previous client structure
+ */
+ struct ClientList *prev;
+
+ /**
+ * Head of the doubly linked list of the currently held locks by this client
+ */
+ struct LockList *ll_head;
+
+ /**
+ * Tail of the doubly linked list of the currently held locks by this client
+ */
+ struct LockList *ll_tail;
+
+ /**
+ * Pointer to the client
+ */
+ struct GNUNET_SERVER_Client *client;
+};
+
+
+/**
+ * Structure for matching a lock
+ */
+struct LockMatch
+{
+ /**
+ * The matched LockingRequest entry; Should be NULL if no entry is found
+ */
+ struct Lock *matched_entry;
+
+ /**
+ * The locking domain name of the lock
+ */
+ const char *domain_name;
+
+ /**
+ * The lock number
+ */
+ uint32_t lock_num;
+};
+
+
+/**
+ * Map of lock-keys to the 'struct LockList' entry for the key.
+ */
+static struct GNUNET_CONTAINER_MultiHashMap *lock_map;
+
+/**
+ * Head of the doubly linked list of clients currently connected
+ */
+static struct ClientList *cl_head;
+
+/**
+ * Tail of the doubly linked list of clients currently connected
+ */
+static struct ClientList *cl_tail;
+
+
+/**
+ * Get the key for the given lock in the 'lock_map'.
+ *
+ * @param domain_name
+ * @param lock_number
+ * @param key set to the key
+ */
+static void
+get_key (const char *domain_name,
+ uint32_t lock_number,
+ struct GNUNET_HashCode *key)
+{
+ uint32_t *last_32;
+
+ GNUNET_CRYPTO_hash (domain_name,
+ strlen (domain_name),
+ key);
+ last_32 = (uint32_t *) key;
+ *last_32 ^= lock_number;
+}
+
+
+/**
+ * Hashmap iterator for matching a lock
+ *
+ * @param cls the LockMatch structure
+ * @param key current key code
+ * @param value value in the hash map (struct Lock)
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+static int
+match_iterator (void *cls, const GNUNET_HashCode *key, void *value)
+{
+ struct LockMatch *match = cls;
+ struct Lock *lock = value;
+
+ if ( (match->lock_num == lock->lock_num)
+ && (0 == strcmp (match->domain_name, lock->domain_name)) )
+ {
+ match->matched_entry = lock;
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+}
+
+
+/**
+ * Function to search for a lock in the global lock hashmap
+ *
+ * @param domain_name the name of the locking domain
+ * @param lock_num the number of the lock
+ * @return the lock if found; NULL if not
+ */
+static struct Lock *
+find_lock (const char *domain_name,
+ const uint32_t lock_num)
+
+{
+ struct LockMatch match;
+ struct GNUNET_HashCode key;
+
+ match.lock_num = lock_num;
+ match.domain_name = domain_name;
+ match.matched_entry = NULL;
+ get_key (domain_name, lock_num, &key);
+ GNUNET_CONTAINER_multihashmap_get_multiple (lock_map,
+ &key,
+ &match_iterator,
+ &match);
+ return match.matched_entry;
+}
+
+
+/**
+ * Adds a lock to the global lock hashmap
+ *
+ * @param domain_name the name of the lock's locking domain
+ * @param lock_num the lock number
+ * @return pointer to the lock structure which is added to lock map
+ */
+static struct Lock *
+add_lock (const char *domain_name,
+ uint32_t lock_num)
+{
+ struct Lock *lock;
+ struct GNUNET_HashCode key;
+ size_t domain_name_len;
+
+ lock = GNUNET_malloc (sizeof (struct Lock));
+ domain_name_len = strlen (domain_name) + 1;
+ lock->domain_name = GNUNET_malloc (domain_name_len);
+ strncpy (lock->domain_name, domain_name, domain_name_len);
+ lock->lock_num = lock_num;
+ get_key (domain_name, lock_num, &key);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding a lock with num: %d and domain: %s to the lock map\n",
+ lock->lock_num, lock->domain_name);
+ GNUNET_CONTAINER_multihashmap_put (lock_map,
+ &key,
+ lock,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+ return lock;
+}
+
+
+/**
+ * Removes a lock from the lock map. The WaitList of the lock should be empty
+ *
+ * @param lock the lock to remove
+ */
+static void
+remove_lock (struct Lock *lock)
+{
+ struct GNUNET_HashCode key;
+
+ GNUNET_assert (NULL == lock->wl_head);
+ get_key (lock->domain_name,
+ lock->lock_num,
+ &key);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Removing lock with num: %u, domain: %s from lock map\n",
+ lock->lock_num, lock->domain_name);
+ GNUNET_assert (GNUNET_YES == GNUNET_CONTAINER_multihashmap_remove
+ (lock_map, &key, lock));
+ GNUNET_free (lock->domain_name);
+ GNUNET_free (lock);
+}
+
+
+/**
+ * Find the LockList entry corresponding to the given Lock in a ClientList
+ * entry
+ *
+ * @param cl_entry the ClientList entry whose lock list has to be searched
+ * @param lock the lock which has to be matched
+ * @return the matching LockList entry; NULL if no match is found
+ */
+static struct LockList *
+cl_ll_find_lock (struct ClientList *cl_entry,
+ const struct Lock *lock)
+{
+ struct LockList *ll_entry;
+
+ for (ll_entry = cl_entry->ll_head;
+ NULL != ll_entry; ll_entry = ll_entry->next)
+ {
+ if (lock == ll_entry->lock)
+ return ll_entry;
+ }
+ return NULL;
+}
+
+
+/**
+ * Function to append a lock to the lock list of a ClientList entry
+ *
+ * @param cl_entry the client which currently owns this lock
+ * @param lock the lock to be added to the cl_entry's lock list
+ */
+static void
+cl_ll_add_lock (struct ClientList *cl_entry,
+ struct Lock *lock)
+{
+ struct LockList *ll_entry;
+
+ ll_entry = GNUNET_malloc (sizeof (struct LockList));
+ ll_entry->lock = lock;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding a lock with num: %u and domain: %s to lock list\n",
+ lock->lock_num, lock->domain_name);
+ GNUNET_CONTAINER_DLL_insert_tail (cl_entry->ll_head,
+ cl_entry->ll_tail,
+ ll_entry);
+}
+
+
+/**
+ * Function to delete a lock from the lock list of the given ClientList entry
+ *
+ * @param cl_entry the ClientList entry
+ * @param ll_entry the LockList entry to be deleted
+ */
+static void
+cl_ll_remove_lock (struct ClientList *cl_entry,
+ struct LockList *ll_entry)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Removing lock with num: %u, domain: %s from lock list of a client\n",
+ ll_entry->lock->lock_num,
+ ll_entry->lock->domain_name);
+ GNUNET_assert (NULL != cl_entry->ll_head);
+ GNUNET_CONTAINER_DLL_remove (cl_entry->ll_head,
+ cl_entry->ll_tail,
+ ll_entry);
+ GNUNET_free (ll_entry);
+}
+
+
+/**
+ * Find a WaitList entry in the waiting list of a lock
+ *
+ * @param lock the lock whose wait list has to be searched
+ * @param cl_entry the ClientList entry to be searched
+ * @return the WaitList entry matching the given cl_entry; NULL if not match
+ * was found
+ */
+static struct WaitList *
+lock_wl_find (const struct Lock *lock,
+ const struct ClientList *cl_entry)
+{
+ struct WaitList *wl_entry;
+
+ for (wl_entry = lock->wl_head;
+ NULL != wl_entry;
+ wl_entry = wl_entry->next)
+ {
+ if (cl_entry == wl_entry->cl_entry)
+ return wl_entry;
+ }
+ return NULL;
+}
+
+
+/**
+ * Add a client to the wait list of given lock
+ *
+ * @param lock the lock list entry of a lock
+ * @param cl_entry the client to queue for the lock's wait list
+ */
+static void
+lock_wl_add_client (struct Lock *lock,
+ struct ClientList *cl_entry)
+{
+ struct WaitList *wl_entry;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding a client to lock's wait list (lock num: %u, domain: %s)\n",
+ lock->lock_num,
+ lock->domain_name);
+ wl_entry = GNUNET_malloc (sizeof (struct WaitList));
+ wl_entry->cl_entry = cl_entry;
+ GNUNET_CONTAINER_DLL_insert_tail (lock->wl_head,
+ lock->wl_tail,
+ wl_entry);
+}
+
+
+/**
+ * Remove an entry from the wait list of the given lock
+ *
+ * @param lock the lock
+ * @param wl_entry the wait list entry to be removed
+ */
+static void
+lock_wl_remove (struct Lock *lock,
+ struct WaitList *wl_entry)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Removing client from wait list of lock with num: %u, domain: %s\n",
+ lock->lock_num, lock->domain_name);
+ GNUNET_CONTAINER_DLL_remove (lock->wl_head,
+ lock->wl_tail,
+ wl_entry);
+ GNUNET_free (wl_entry);
+}
+
+
+/**
+ * Search for a client in the client list
+ *
+ * @param client the client to be searched for
+ * @return the ClientList entry; NULL if the client is not found
+ */
+static struct ClientList *
+cl_find_client (const struct GNUNET_SERVER_Client *client)
+{
+ struct ClientList *current;
+
+ for (current = cl_head; NULL != current; current = current->next)
+ if (client == current->client)
+ return current;
+ return NULL;
+}
+
+
+/**
+ * Append a client to the client list
+ *
+ * @param client the client to be appended to the list
+ * @return the client list entry which is added to the client list
+ */
+static struct ClientList *
+cl_add_client (struct GNUNET_SERVER_Client *client)
+{
+ struct ClientList *new_client;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Adding a client to the client list\n");
+ new_client = GNUNET_malloc (sizeof (struct ClientList));
+ GNUNET_SERVER_client_keep (client);
+ new_client->client = client;
+ GNUNET_CONTAINER_DLL_insert_tail (cl_head,
+ cl_tail,
+ new_client);
+ return new_client;
+}
+
+
+/**
+ * Delete the given client from the client list. The LockList should be empty
+ *
+ * @param cl_entry the client list entry to delete
+ */
+static void
+cl_remove_client (struct ClientList *cl_entry)
+{
+ GNUNET_assert (NULL == cl_entry->ll_head);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Removing a client from the client list\n");
+ GNUNET_SERVER_client_drop (cl_entry->client);
+ GNUNET_CONTAINER_DLL_remove (cl_head,
+ cl_tail,
+ cl_entry);
+ GNUNET_free (cl_entry);
+}
+
+
+/**
+ * Transmit notify for sending message to client
+ *
+ * @param cls the message to send
+ * @param size number of bytes available in buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to buf
+ */
+static size_t
+transmit_notify (void *cls, size_t size, void *buf)
+{
+ struct GNUNET_LOCKMANAGER_Message *msg = cls;
+ uint16_t msg_size;
+
+ if ((0 == size) || (NULL == buf))
+ {
+ /* FIXME: Timed out -- requeue? */
+ return 0;
+ }
+ msg_size = ntohs (msg->header.size);
+ GNUNET_assert (size >= msg_size);
+ memcpy (buf, msg, msg_size);
+ GNUNET_free (msg);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Message of size %u sent\n", msg_size);
+ return msg_size;
+}
+
+
+/**
+ * Send SUCCESS message to the client
+ *
+ * @param client the client to which the message has to be sent
+ * @param domain_name the locking domain of the successfully acquried lock
+ * @param lock_num the number of the successfully acquired lock
+ */
+static void
+send_success_msg (struct GNUNET_SERVER_Client *client,
+ const char *domain_name,
+ int lock_num)
+{
+ struct GNUNET_LOCKMANAGER_Message *reply;
+ size_t domain_name_len;
+ uint16_t reply_size;
+
+ domain_name_len = strlen (domain_name) + 1;
+ reply_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_len;
+ reply = GNUNET_malloc (reply_size);
+ reply->header.size = htons (reply_size);
+ reply->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS);
+ reply->lock = htonl (lock_num);
+ strncpy ((char *) &reply[1], domain_name, domain_name_len);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Sending SUCCESS message for lock with num: %u, domain: %s\n",
+ lock_num, domain_name);
+ GNUNET_SERVER_notify_transmit_ready (client,
+ reply_size,
+ TIMEOUT,
+ &transmit_notify,
+ reply);
+}
+
+
+/**
+ * Handler for GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE
+ *
+ * @param cls NULL
+ * @param client the client sending this message
+ * @param message GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE message
+ */
+static void
+handle_acquire (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct GNUNET_LOCKMANAGER_Message *request;
+ const char *domain_name;
+ struct Lock *lock;
+ struct ClientList *cl_entry;
+ uint32_t lock_num;
+ uint16_t msize;
+
+ msize = htons (message->size);
+ if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ request = (struct GNUNET_LOCKMANAGER_Message *) message;
+ domain_name = (const char *) &request[1];
+ msize -= sizeof (struct GNUNET_LOCKMANAGER_Message);
+ if ('\0' != domain_name[msize])
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ lock_num = ntohl (request->lock);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received an ACQUIRE message for lock num: %u domain: %s\n",
+ lock_num, domain_name);
+ if (NULL == (cl_entry = cl_find_client (client)))
+ cl_entry = cl_add_client (client); /* Add client if not in client list */
+ if (NULL != (lock = find_lock (domain_name,lock_num)))
+ {
+ if (lock->cl_entry == cl_entry)
+ { /* Client is requesting a lock it already owns */
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ lock_wl_add_client (lock, cl_entry);
+ cl_ll_add_lock (cl_entry, lock);
+ }
+ else /* Lock not present */
+ {
+ lock = add_lock (domain_name, lock_num);
+ lock->cl_entry = cl_entry;
+ cl_ll_add_lock (cl_entry, lock);
+ send_success_msg (cl_entry->client, domain_name, lock_num);
+ }
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
+ * This function gives the lock to the first client in the wait list of the
+ * lock. If no clients are currently waiting for this lock, the lock is then
+ * destroyed.
+ *
+ * @param lock the lock which has to be processed for release
+ */
+static void
+process_lock_release (struct Lock *lock)
+{
+ struct WaitList *wl_entry;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Processing lock release for lock with num: %u, domain: %s\n",
+ lock->lock_num, lock->domain_name);
+ wl_entry = lock->wl_head;
+ if (NULL == wl_entry)
+ {
+ remove_lock (lock); /* No clients waiting for this lock - delete */
+ return;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Giving lock to a client from wait list\n");
+ lock->cl_entry = wl_entry->cl_entry;
+ lock_wl_remove(lock, wl_entry);
+ send_success_msg (lock->cl_entry->client,
+ lock->domain_name,
+ lock->lock_num);
+ return;
+}
+
+
+/**
+ * Handle for GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE
+ *
+ * @param cls NULL
+ * @param client the client sending this message
+ * @param message the LOCKMANAGER_RELEASE message
+ */
+static void
+handle_release (void *cls,
+ struct GNUNET_SERVER_Client *client,
+ const struct GNUNET_MessageHeader *message)
+{
+ const struct GNUNET_LOCKMANAGER_Message *request;
+ struct ClientList *cl_entry;
+ struct WaitList *wl_entry;
+ struct LockList *ll_entry;
+ const char *domain_name;
+ struct Lock *lock;
+ uint32_t lock_num;
+ uint16_t msize;
+
+ msize = ntohs (message->size);
+ if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ request = (const struct GNUNET_LOCKMANAGER_Message *) message;
+ domain_name = (const char *) &request[1];
+ msize -= sizeof (struct GNUNET_LOCKMANAGER_Message);
+ if ('\0' != domain_name[msize-1])
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+
+
+ }
+ lock_num = ntohl (request->lock);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received RELEASE message for lock with num: %d, domain: %s\n",
+ lock_num, domain_name);
+ if (NULL == (cl_entry = cl_find_client (client)))
+ {
+ GNUNET_break(0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ lock = find_lock (domain_name, lock_num);
+ if(NULL == lock)
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ if (NULL == (ll_entry = cl_ll_find_lock (cl_entry, lock)))
+ {
+ GNUNET_break (0);
+ GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+ return;
+ }
+ cl_ll_remove_lock (cl_entry, ll_entry);
+ if (cl_entry == lock->cl_entry)
+ {
+ process_lock_release (lock);
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+ return;
+ }
+ /* remove 'client' from wait list (check that it is not there...) */
+ if (NULL != (wl_entry = lock_wl_find (lock, cl_entry)))
+ {
+ lock_wl_remove (lock, wl_entry);
+ }
+ GNUNET_SERVER_receive_done (client, GNUNET_OK);
+}
+
+
+/**
+ * Callback for client disconnect
+ *
+ * @param cls NULL
+ * @param client the client which has disconnected
+ */
+static void
+client_disconnect_cb (void *cls, struct GNUNET_SERVER_Client *client)
+{
+ struct ClientList *cl_entry;
+ struct LockList *ll_entry;
+ struct Lock *lock;
+
+ if (NULL == client)
+ return;
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "A client has been disconnected -- freeing its locks and resources\n");
+ cl_entry = cl_find_client (client);
+ if (NULL == cl_entry)
+ return;
+ while (NULL != (ll_entry = cl_entry->ll_head))
+ {
+ lock = ll_entry->lock;
+ cl_ll_remove_lock (cl_entry, ll_entry);
+ process_lock_release (lock);
+ }
+ cl_remove_client (cl_entry);
+}
+
+
+/**
+ * Hashmap Iterator to delete lock entries in hash map
+ *
+ * @param cls NULL
+ * @param key current key code
+ * @param value value in the hash map
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+static int
+lock_delete_iterator (void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct Lock *lock = value;
+
+ GNUNET_assert (NULL != lock);
+ while (NULL != lock->wl_head)
+ {
+ lock_wl_remove (lock, lock->wl_head);
+ }
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove(lock_map,
+ key,
+ lock));
+ GNUNET_free (lock->domain_name);
+ GNUNET_free (lock);
+ return GNUNET_YES;
+}
+
+
+/**
+ * Task to clean up and shutdown nicely
+ *
+ * @param cls NULL
+ * @param tc the TaskContext from scheduler
+ */
+static void
+shutdown_task (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Shutting down lock manager\n");
+ /* Clean the global ClientList */
+ while (NULL != cl_head)
+ {
+ while (NULL != cl_head->ll_head) /* Clear the LockList */
+ {
+ cl_ll_remove_lock (cl_head, cl_head->ll_head);
+ }
+ cl_remove_client (cl_head);
+ }
+ /* Clean the global hash table */
+ GNUNET_CONTAINER_multihashmap_iterate (lock_map,
+ &lock_delete_iterator,
+ NULL);
+ GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (lock_map));
+ GNUNET_CONTAINER_multihashmap_destroy (lock_map);
+}
+
+
+/**
+ * Lock manager setup
+ *
+ * @param cls closure
+ * @param server the initialized server
+ * @param cfg configuration to use
+ */
+static void
+lockmanager_run (void *cls,
+ struct GNUNET_SERVER_Handle * server,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ static const struct GNUNET_SERVER_MessageHandler message_handlers[] =
+ {
+ {&handle_acquire, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE, 0},
+ {&handle_release, NULL, GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE, 0},
+ {NULL}
+ };
+ GNUNET_SERVER_add_handlers (server,
+ message_handlers);
+ GNUNET_SERVER_disconnect_notify (server,
+ &client_disconnect_cb,
+ NULL);
+ lock_map = GNUNET_CONTAINER_multihashmap_create (30);
+ GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL,
+ &shutdown_task,
+ NULL);
+}
+
+
+/**
+ * The starting point of execution
+ */
+int main (int argc, char *const *argv)
+{
+ return
+ (GNUNET_OK ==
+ GNUNET_SERVICE_run (argc,
+ argv,
+ "lockmanager",
+ GNUNET_SERVICE_OPTION_NONE,
+ &lockmanager_run,
+ NULL)) ? 0 : 1;
+}
diff --git a/src/lockmanager/lockmanager.conf.in b/src/lockmanager/lockmanager.conf.in
new file mode 100644
index 0000000..75b9244
--- /dev/null
+++ b/src/lockmanager/lockmanager.conf.in
@@ -0,0 +1,13 @@
+[lockmanager]
+AUTOSTART = YES
+@UNIXONLY@ PORT = 2100
+HOSTNAME = localhost
+HOME = $SERVICEHOME
+CONFIG = $DEFAULTCONFIG
+BINARY = gnunet-service-lockmanager
+ACCEPT_FROM = 127.0.0.1;
+ACCEPT_FROM6 = ::1;
+UNIXPATH = /tmp/gnunet-service-lockmanager.sock
+UNIX_MATCH_UID = YES
+UNIX_MATCH_GID = YES
+
diff --git a/src/lockmanager/lockmanager.h b/src/lockmanager/lockmanager.h
new file mode 100644
index 0000000..346c43e
--- /dev/null
+++ b/src/lockmanager/lockmanager.h
@@ -0,0 +1,71 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file lockmanager/lockmanager.h
+ * @brief client-server protocol messages for LOCKMANAGER service
+ * @author Sree Harsha Totakura
+ */
+
+#ifndef LOCKMANAGER_H
+#define LOCKMANAGER_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#if 0 /* keep Emacsens' auto-indent happy */
+}
+#endif
+#endif
+
+#include "gnunet_common.h"
+
+/**
+ * Structure of Lockmanager message
+ */
+struct GNUNET_LOCKMANAGER_Message
+{
+ /**
+ * The generic message header
+ */
+ struct GNUNET_MessageHeader header;
+
+ /**
+ * The lock
+ */
+ uint32_t lock;
+
+ /**
+ * The locking domain name(NULL terminated string of characters) should
+ * follow here. The size of the header should include the size of this string
+ * with its trailing NULL
+ */
+};
+
+#if 0 /* keep Emacsens' auto-indent happy */
+{
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+/* ifndef LOCKMANAGER_H */
+#endif
+/* end of lockmanager.h */
diff --git a/src/lockmanager/lockmanager_api.c b/src/lockmanager/lockmanager_api.c
new file mode 100644
index 0000000..99f5ab5
--- /dev/null
+++ b/src/lockmanager/lockmanager_api.c
@@ -0,0 +1,677 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file lockmanager/lockmanager_api.c
+ * @brief API implementation of gnunet_lockmanager_service.h
+ * @author Sree Harsha Totakura
+ */
+
+/**
+ * To be fixed:
+ * Should the handle be freed when the connection to service is lost?
+ * Should cancel_request have a call back (else simultaneous calls break)
+ */
+
+#include "platform.h"
+#include "gnunet_common.h"
+#include "gnunet_container_lib.h"
+#include "gnunet_client_lib.h"
+#include "gnunet_crypto_lib.h"
+#include "gnunet_lockmanager_service.h"
+#include "gnunet_protocols.h"
+
+#include "lockmanager.h"
+
+#define LOG(kind,...) \
+ GNUNET_log_from (kind, "lockmanager-api",__VA_ARGS__)
+
+#define TIME_REL_MINS(min) \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, min)
+
+#define TIMEOUT TIME_REL_MINS(3)
+
+
+/**
+ * The message queue
+ */
+struct MessageQueue
+{
+ /**
+ * The next pointer for doubly linked list
+ */
+ struct MessageQueue *next;
+
+ /**
+ * The prev pointer for doubly linked list
+ */
+ struct MessageQueue *prev;
+
+ /**
+ * The LOCKMANAGER Message
+ */
+ struct GNUNET_LOCKMANAGER_Message *msg;
+};
+
+
+/**
+ * Handler for the lockmanager service
+ */
+struct GNUNET_LOCKMANAGER_Handle
+{
+ /**
+ * The client connection to the service
+ */
+ struct GNUNET_CLIENT_Connection *conn;
+
+ /**
+ * The transmit handle for transmissions using conn
+ */
+ struct GNUNET_CLIENT_TransmitHandle *transmit_handle;
+
+ /**
+ * Hashmap handle
+ */
+ struct GNUNET_CONTAINER_MultiHashMap *hashmap;
+
+ /**
+ * Double linked list head for message queue
+ */
+ struct MessageQueue *mq_head;
+
+ /**
+ * Double linked list tail for message queue
+ */
+ struct MessageQueue *mq_tail;
+};
+
+
+/**
+ * Structure for Locking Request
+ */
+struct GNUNET_LOCKMANAGER_LockingRequest
+{
+ /**
+ * The handle associated with this request
+ */
+ struct GNUNET_LOCKMANAGER_Handle *handle;
+
+ /**
+ * The status callback
+ */
+ GNUNET_LOCKMANAGER_StatusCallback status_cb;
+
+ /**
+ * Closure for the status callback
+ */
+ void *status_cb_cls;
+
+ /**
+ * The locking domain of this request
+ */
+ char *domain;
+
+ /**
+ * The lock
+ */
+ uint32_t lock;
+
+ /**
+ * The status of the lock
+ */
+ enum GNUNET_LOCKMANAGER_Status status;
+};
+
+
+/**
+ * Structure for matching a lock
+ */
+struct LockingRequestMatch
+{
+ /**
+ * The matched LockingRequest entry; Should be NULL if no entry is found
+ */
+ struct GNUNET_LOCKMANAGER_LockingRequest *matched_entry;
+
+ /**
+ * The locking domain name of the lock
+ */
+ const char *domain;
+
+ /**
+ * The lock number
+ */
+ uint32_t lock;
+};
+
+
+/**
+ * Transmit notify for sending message to server
+ *
+ * @param cls the lockmanager handle
+ * @param size number of bytes available in buf
+ * @param buf where the callee should write the message
+ * @return number of bytes written to buf
+ */
+static size_t
+transmit_notify (void *cls, size_t size, void *buf)
+{
+ struct GNUNET_LOCKMANAGER_Handle *handle = cls;
+ struct MessageQueue *queue_entity;
+ uint16_t msg_size;
+
+ handle->transmit_handle = NULL;
+ if ((0 == size) || (NULL == buf))
+ {
+ /* FIXME: Timed out -- requeue? */
+ return 0;
+ }
+ queue_entity = handle->mq_head;
+ GNUNET_assert (NULL != queue_entity);
+ msg_size = ntohs (queue_entity->msg->header.size);
+ GNUNET_assert (size >= msg_size);
+ memcpy (buf, queue_entity->msg, msg_size);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Message of size %u sent\n", msg_size);
+ GNUNET_free (queue_entity->msg);
+ GNUNET_CONTAINER_DLL_remove (handle->mq_head,
+ handle->mq_tail,
+ queue_entity);
+ GNUNET_free (queue_entity);
+ queue_entity = handle->mq_head;
+ if (NULL != queue_entity)
+ {
+ handle->transmit_handle =
+ GNUNET_CLIENT_notify_transmit_ready (handle->conn,
+ ntohs
+ (queue_entity->msg->header.size),
+ TIMEOUT,
+ GNUNET_YES,
+ &transmit_notify,
+ handle);
+ }
+ return msg_size;
+}
+
+
+/**
+ * Queues a message into handle's send message queue
+ *
+ * @param handle the lockmanager handle whose queue will be used
+ * @param msg the message to be queued
+ */
+static void
+queue_message (struct GNUNET_LOCKMANAGER_Handle *handle,
+ struct GNUNET_LOCKMANAGER_Message *msg)
+{
+ struct MessageQueue *queue_entity;
+
+ GNUNET_assert (NULL != msg);
+ queue_entity = GNUNET_malloc (sizeof (struct MessageQueue));
+ queue_entity->msg = msg;
+ GNUNET_CONTAINER_DLL_insert_tail (handle->mq_head,
+ handle->mq_tail,
+ queue_entity);
+ if (NULL == handle->transmit_handle)
+ {
+ handle->transmit_handle =
+ GNUNET_CLIENT_notify_transmit_ready (handle->conn,
+ ntohs (msg->header.size),
+ TIMEOUT,
+ GNUNET_YES,
+ &transmit_notify,
+ handle);
+ }
+}
+
+
+/**
+ * Get the key for the given lock in the 'lock_map'.
+ *
+ * @param domain_name
+ * @param lock_number
+ * @param key set to the key
+ */
+static void
+get_key (const char *domain_name,
+ uint32_t lock_number,
+ struct GNUNET_HashCode *key)
+{
+ uint32_t *last_32;
+
+ GNUNET_CRYPTO_hash (domain_name,
+ strlen (domain_name),
+ key);
+ last_32 = (uint32_t *) key;
+ *last_32 ^= lock_number;
+}
+
+
+/**
+ * Hashmap iterator for matching a LockingRequest
+ *
+ * @param cls the LockingRequestMatch structure
+ * @param key current key code
+ * @param value value in the hash map (struct GNUNET_LOCKMANAGER_LockingRequest)
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+static int
+match_iterator (void *cls, const GNUNET_HashCode *key, void *value)
+{
+ struct LockingRequestMatch *match = cls;
+ struct GNUNET_LOCKMANAGER_LockingRequest *lr = value;
+
+ if ( (match->lock == lr->lock) && (0 == strcmp (match->domain, lr->domain)) )
+ {
+ match->matched_entry = lr;
+ return GNUNET_NO;
+ }
+ return GNUNET_YES;
+}
+
+
+/**
+ * Function to find a LockingRequest associated with the given domain and lock
+ * attributes in the map
+ *
+ * @param map the map where the LockingRequests are stored
+ * @param domain the locking domain name
+ * @param lock the lock number
+ * @return the found LockingRequest; NULL if a matching LockingRequest wasn't
+ * found
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *
+hashmap_find_lockingrequest (const struct GNUNET_CONTAINER_MultiHashMap *map,
+ const char *domain,
+ uint32_t lock)
+{
+ struct GNUNET_HashCode hash;
+ struct LockingRequestMatch lock_match;
+
+ lock_match.matched_entry = NULL;
+ lock_match.domain = domain;
+ lock_match.lock = lock;
+ get_key (domain, lock, &hash);
+ GNUNET_CONTAINER_multihashmap_get_multiple (map,
+ &hash,
+ &match_iterator,
+ &lock_match);
+ return lock_match.matched_entry;
+}
+
+
+/**
+ * Task for calling status change callback for a lock
+ *
+ * @param cls the LockingRequest associated with this lock
+ * @param tc the TaskScheduler context
+ */
+static void
+call_status_cb_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ const struct GNUNET_LOCKMANAGER_LockingRequest *r = cls;
+
+ if (NULL != r->status_cb)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Calling status change for SUCCESS on lock num: %d, domain: %s\n",
+ r->lock, r->domain);
+ r->status_cb (r->status_cb_cls,
+ r->domain,
+ r->lock,
+ r->status);
+ }
+}
+
+
+/**
+ * Iterator to call relase and free all LockingRequest entries
+ *
+ * @param cls the lockmanager handle
+ * @param key current key code
+ * @param value the Locking request
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+static int
+release_iterator(void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct GNUNET_LOCKMANAGER_Handle *h = cls;
+ struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
+
+ if (NULL != r->status_cb)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Calling status change for RELEASE on lock num: %d, domain: %s\n",
+ r->lock, r->domain);
+ r->status_cb (r->status_cb_cls,
+ r->domain,
+ r->lock,
+ GNUNET_LOCKMANAGER_RELEASE);
+ }
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove (h->hashmap,
+ key,
+ value));
+ GNUNET_free (r->domain);
+ GNUNET_free (r);
+ return GNUNET_YES;
+}
+
+
+/**
+ * Handler for server replies
+ *
+ * @param cls the LOCKMANAGER_Handle
+ * @param msg received message, NULL on timeout or fatal error
+ */
+static void
+handle_replies (void *cls,
+ const struct GNUNET_MessageHeader *msg)
+{
+ struct GNUNET_LOCKMANAGER_Handle *handle = cls;
+ const struct GNUNET_LOCKMANAGER_Message *m;
+ struct GNUNET_LOCKMANAGER_LockingRequest *lr;
+ const char *domain;
+ struct GNUNET_HashCode hash;
+ uint32_t lock;
+ uint16_t msize;
+
+ if (NULL == msg)
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Lockmanager service not available or went down\n");
+ /* Should release all locks and free its locking requests */
+ GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap,
+ &release_iterator,
+ handle);
+ return;
+ }
+ GNUNET_CLIENT_receive (handle->conn,
+ &handle_replies,
+ handle,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+ if (GNUNET_MESSAGE_TYPE_LOCKMANAGER_SUCCESS != ntohs(msg->type))
+ {
+ GNUNET_break (0);
+ return;
+ }
+ msize = ntohs (msg->size);
+ if (msize <= sizeof (struct GNUNET_LOCKMANAGER_Message))
+ {
+ GNUNET_break (0);
+ return;
+ }
+ m = (const struct GNUNET_LOCKMANAGER_Message *) msg;
+ domain = (const char *) &m[1];
+ msize -= sizeof (struct GNUNET_LOCKMANAGER_Message);
+ if ('\0' != domain[msize-1])
+ {
+ GNUNET_break (0);
+ return;
+ }
+
+ lock = ntohl (m->lock);
+ get_key (domain, lock, &hash);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received SUCCESS message for lock: %d, domain %s\n",
+ lock, domain);
+ if (NULL == (lr = hashmap_find_lockingrequest (handle->hashmap,
+ domain,
+ lock)))
+ {
+ GNUNET_break (0);
+ return;
+ }
+ if (GNUNET_LOCKMANAGER_SUCCESS == lr->status)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Changing status for lock: %d in domain: %s to SUCCESS\n",
+ lr->lock, lr->domain);
+ lr->status = GNUNET_LOCKMANAGER_SUCCESS;
+ GNUNET_SCHEDULER_add_continuation (&call_status_cb_task,
+ lr,
+ GNUNET_SCHEDULER_REASON_PREREQ_DONE);
+}
+
+
+/**
+ * Iterator to free hash map entries.
+ *
+ * @param cls the lockmanger handle
+ * @param key current key code
+ * @param value the Locking request
+ * @return GNUNET_YES if we should continue to
+ * iterate,
+ * GNUNET_NO if not.
+ */
+static int
+free_iterator(void *cls,
+ const GNUNET_HashCode * key,
+ void *value)
+{
+ struct GNUNET_LOCKMANAGER_Handle *h = cls;
+ struct GNUNET_LOCKMANAGER_LockingRequest *r = value;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Clearing locking request\n");
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove (h->hashmap,
+ key,
+ value));
+ GNUNET_free (r->domain);
+ GNUNET_free (r);
+ return GNUNET_YES;
+}
+
+
+/*******************/
+/* API Definitions */
+/*******************/
+
+
+/**
+ * Connect to the lockmanager service
+ *
+ * @param cfg the configuration to use
+ *
+ * @return upon success the handle to the service; NULL upon error
+ */
+struct GNUNET_LOCKMANAGER_Handle *
+GNUNET_LOCKMANAGER_connect (const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ struct GNUNET_LOCKMANAGER_Handle *h;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
+ h = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_Handle));
+ h->conn = GNUNET_CLIENT_connect ("lockmanager", cfg);
+ if (NULL == h->conn)
+ {
+ GNUNET_free (h);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
+ return NULL;
+ }
+ h->hashmap = GNUNET_CONTAINER_multihashmap_create (15);
+ GNUNET_assert (NULL != h->hashmap);
+ GNUNET_CLIENT_receive (h->conn,
+ &handle_replies,
+ h,
+ GNUNET_TIME_UNIT_FOREVER_REL);
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
+ return h;
+}
+
+
+/**
+ * Disconnect from the lockmanager service
+ *
+ * @param handle the handle to the lockmanager service
+ */
+void
+GNUNET_LOCKMANAGER_disconnect (struct GNUNET_LOCKMANAGER_Handle *handle)
+{
+ struct MessageQueue *head;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
+ if (0 != GNUNET_CONTAINER_multihashmap_size (handle->hashmap))
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING,
+ "Some locking requests are still present. Cancel them before "
+ "calling %s\n", __func__);
+ GNUNET_CONTAINER_multihashmap_iterate (handle->hashmap,
+ &free_iterator,
+ handle);
+ }
+ GNUNET_CONTAINER_multihashmap_destroy (handle->hashmap);
+ /* Clear the message queue */
+ if (NULL != handle->transmit_handle)
+ {
+ GNUNET_CLIENT_notify_transmit_ready_cancel (handle->transmit_handle);
+ }
+ head = handle->mq_head;
+ while (NULL != head)
+ {
+ GNUNET_CONTAINER_DLL_remove (handle->mq_head,
+ handle->mq_tail,
+ head);
+ GNUNET_free (head->msg);
+ GNUNET_free (head);
+ head = handle->mq_head;
+ }
+ GNUNET_CLIENT_disconnect (handle->conn);
+ GNUNET_free (handle);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
+}
+
+
+/**
+ * Tries to acquire the given lock(even if the lock has been lost) until the
+ * request is called. If the lock is available the status_cb will be
+ * called. If the lock is busy then the request is queued and status_cb
+ * will be called when the lock has been made available and acquired by us.
+ *
+ * @param handle the handle to the lockmanager service
+ *
+ * @param domain_name name of the locking domain. Clients who want to share
+ * locks must use the same name for the locking domain. Also the
+ * domain_name should be selected with the prefix
+ * "GNUNET_<PROGRAM_NAME>_" to avoid domain name collisions.
+ *
+ *
+ * @param lock which lock to lock
+ *
+ * @param status_cb the callback for signalling when the lock is acquired and
+ * when it is lost
+ *
+ * @param status_cb_cls the closure to the above callback
+ *
+ * @return the locking request handle for this request
+ */
+struct GNUNET_LOCKMANAGER_LockingRequest *
+GNUNET_LOCKMANAGER_acquire_lock (struct GNUNET_LOCKMANAGER_Handle *handle,
+ const char *domain_name,
+ uint32_t lock,
+ GNUNET_LOCKMANAGER_StatusCallback
+ status_cb,
+ void *status_cb_cls)
+{
+ struct GNUNET_LOCKMANAGER_LockingRequest *r;
+ struct GNUNET_LOCKMANAGER_Message *msg;
+ struct GNUNET_HashCode hash;
+ uint16_t msg_size;
+ size_t domain_name_length;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
+ r = GNUNET_malloc (sizeof (struct GNUNET_LOCKMANAGER_LockingRequest));
+ domain_name_length = strlen (domain_name) + 1;
+ r->handle = handle;
+ r->lock = lock;
+ r->domain = GNUNET_malloc (domain_name_length);
+ r->status = GNUNET_LOCKMANAGER_RELEASE;
+ r->status_cb = status_cb;
+ r->status_cb_cls = status_cb_cls;
+ memcpy (r->domain, domain_name, domain_name_length);
+ msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message) + domain_name_length;
+ msg = GNUNET_malloc (msg_size);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_ACQUIRE);
+ msg->header.size = htons (msg_size);
+ msg->lock = htonl (lock);
+ memcpy (&msg[1], r->domain, domain_name_length);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Queueing ACQUIRE message\n");
+ queue_message (handle, msg);
+ get_key (r->domain, r->lock, &hash);
+ GNUNET_CONTAINER_multihashmap_put (r->handle->hashmap,
+ &hash,
+ r,
+ GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
+ return r;
+}
+
+
+
+/**
+ * Function to cancel the locking request generated by
+ * GNUNET_LOCKMANAGER_acquire_lock. If the lock is acquired us then the lock is
+ * released. GNUNET_LOCKMANAGER_StatusCallback will not be called upon any
+ * status changes resulting due to this call.
+ *
+ * @param request the LockingRequest to cancel
+ */
+void
+GNUNET_LOCKMANAGER_cancel_request (struct GNUNET_LOCKMANAGER_LockingRequest
+ *request)
+{
+ struct GNUNET_LOCKMANAGER_Message *msg;
+ struct GNUNET_HashCode hash;
+ uint16_t msg_size;
+ size_t domain_name_length;
+
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s()\n", __func__);
+ /* FIXME: Stop ACQUIRE retransmissions */
+ if (GNUNET_LOCKMANAGER_SUCCESS == request->status)
+ {
+ domain_name_length = strlen (request->domain) + 1;
+ msg_size = sizeof (struct GNUNET_LOCKMANAGER_Message)
+ + domain_name_length;
+ msg = GNUNET_malloc (msg_size);
+ msg->header.type = htons (GNUNET_MESSAGE_TYPE_LOCKMANAGER_RELEASE);
+ msg->header.size = htons (msg_size);
+ msg->lock = htonl (request->lock);
+ memcpy (&msg[1], request->domain, domain_name_length);
+ queue_message (request->handle, msg);
+ }
+ get_key (request->domain, request->lock, &hash);
+ GNUNET_assert (GNUNET_YES ==
+ GNUNET_CONTAINER_multihashmap_remove
+ (request->handle->hashmap, &hash, request));
+ GNUNET_free (request->domain);
+ GNUNET_free (request);
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "%s() END\n", __func__);
+}
diff --git a/src/lockmanager/test_lockmanager_api.c b/src/lockmanager/test_lockmanager_api.c
new file mode 100644
index 0000000..e8d0412
--- /dev/null
+++ b/src/lockmanager/test_lockmanager_api.c
@@ -0,0 +1,279 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file lockmanager/test_lockmanager_api.c
+ * @brief Test cases for lockmanager_api.c
+ * @author Sree Harsha Totakura
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_lockmanager_service.h"
+
+#define VERBOSE GNUNET_YES
+
+#define VERBOSE_ARM 1
+
+#define LOG(kind,...) \
+ GNUNET_log (kind, __VA_ARGS__)
+
+#define TIME_REL_SECONDS(min) \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min)
+
+
+/**
+ * Enumeration of testing steps
+ */
+enum Test
+ {
+ TEST_FAIL,
+
+ TEST_INIT,
+
+ LOCK1_ACQUIRE,
+
+ LOCK2_ACQUIRE
+ };
+
+
+/**
+ * The testing result
+ */
+static enum Test result;
+
+/**
+ * The process id of the GNUNET ARM process
+ */
+static struct GNUNET_OS_Process *arm_pid = NULL;
+
+/**
+ * Configuration Handle
+ */
+static struct GNUNET_CONFIGURATION_Handle *config;
+
+/**
+ * The handle to the lockmanager service
+ */
+static struct GNUNET_LOCKMANAGER_Handle *handle;
+
+/**
+ * The locking request
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *request;
+
+/**
+ * The second locking request
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *request2;
+
+/**
+ * Abort task identifier
+ */
+static GNUNET_SCHEDULER_TaskIdentifier abort_task_id;
+
+/**
+ * Shutdown nicely
+ *
+ * @param cls
+ * @param tc the task context
+ */
+static void
+do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (GNUNET_SCHEDULER_NO_TASK != abort_task_id)
+ {
+ GNUNET_SCHEDULER_cancel (abort_task_id);
+ abort_task_id = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != request)
+ GNUNET_LOCKMANAGER_cancel_request (request);
+ if (NULL != request2)
+ GNUNET_LOCKMANAGER_cancel_request (request2);
+ GNUNET_LOCKMANAGER_disconnect (handle);
+ if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Kill gnunet-service-arm manually\n");
+ }
+ GNUNET_OS_process_wait (arm_pid);
+ GNUNET_OS_process_destroy (arm_pid);
+
+ if (NULL != config)
+ GNUNET_CONFIGURATION_destroy (config);
+}
+
+
+/**
+ * Shutdown nicely
+ *
+ * @param cls
+ * @param tc the task context
+ */
+static void
+do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n");
+ abort_task_id = GNUNET_SCHEDULER_NO_TASK;
+ result = TEST_FAIL;
+ do_shutdown (cls, tc);
+}
+
+/**
+ * Callback for lock status changes
+ *
+ * @param cls the closure from GNUNET_LOCKMANAGER_lock call
+ *
+ * @param domain_name the locking domain of the lock
+ *
+ * @param lock the lock for which this status is relevant
+ *
+ * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully
+ * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost
+ */
+static void
+status_cb (void *cls,
+ const char *domain_name,
+ uint32_t lock,
+ enum GNUNET_LOCKMANAGER_Status status)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Status change callback called on lock: %d of domain: %s\n",
+ lock, domain_name);
+ switch (result)
+ {
+ case LOCK1_ACQUIRE:
+ GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
+ GNUNET_assert (NULL != request);
+ //GNUNET_LOCKMANAGER_cancel_request (request);
+ //request = NULL;
+ result = LOCK2_ACQUIRE;
+ request2 = GNUNET_LOCKMANAGER_acquire_lock (handle,
+ "GNUNET_LOCKMANAGER_TESTING",
+ 100,
+ &status_cb,
+ NULL);
+ GNUNET_assert (NULL != request2);
+ break;
+ case LOCK2_ACQUIRE:
+ GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
+ GNUNET_assert (NULL != request);
+ GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1),
+ &do_shutdown,
+ NULL);
+ break;
+ default:
+ GNUNET_break (0);
+ }
+}
+
+
+/**
+ * Testing function
+ *
+ * @param cls NULL
+ * @param tc the task context
+ */
+static void
+test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ handle = GNUNET_LOCKMANAGER_connect (config);
+ GNUNET_assert (NULL != handle);
+ result = LOCK1_ACQUIRE;
+ request = GNUNET_LOCKMANAGER_acquire_lock (handle,
+ "GNUNET_LOCKMANAGER_TESTING",
+ 99,
+ &status_cb,
+ NULL);
+ abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10),
+ &do_abort,
+ NULL);
+}
+
+
+/**
+ * Main point of test execution
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n");
+ config = GNUNET_CONFIGURATION_dup (cfg);
+ arm_pid =
+ GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm",
+#if VERBOSE_ARM
+ "-L", "DEBUG",
+#endif
+ "-c", "test_lockmanager_api.conf", NULL);
+
+ GNUNET_assert (NULL != arm_pid);
+ GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (3),
+ &test,
+ NULL);
+}
+
+
+/**
+ * Main function
+ */
+int main (int argc, char **argv)
+{
+ int ret;
+
+ char *const argv2[] = { "test-lockmanager-api",
+ "-c", "test_lockmanager_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ GNUNET_log_setup ("test-lockmanager-api",
+#if VERBOSE
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL);
+
+ ret =
+ GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
+ "test-lockmanager-api", "nohelp", options, &run, NULL);
+
+ if (GNUNET_OK != ret)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n",
+ ret);
+ return 1;
+ }
+ if (TEST_FAIL == result)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n");
+ return 1;
+ }
+ LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n");
+ return 0;
+}
diff --git a/src/lockmanager/test_lockmanager_api.conf b/src/lockmanager/test_lockmanager_api.conf
new file mode 100644
index 0000000..894f409
--- /dev/null
+++ b/src/lockmanager/test_lockmanager_api.conf
@@ -0,0 +1,73 @@
+[lockmanager]
+DEBUG = YES
+AUTOSTART = NO
+PORT = 12112
+ACCEPT_FROM = 127.0.0.1;
+HOSTNAME = localhost
+# PREFIX = valgrind --leak-check=full
+# PREFIX = xterm -geometry 100x85 -T peer1 -e libtool --mode=execute gdb --args
+
+[fs]
+AUTOSTART = NO
+
+[resolver]
+AUTOSTART = NO
+
+[mesh]
+AUTOSTART = NO
+
+[dht]
+AUTOSTART = NO
+
+[block]
+plugins = dht test
+
+[dhtcache]
+QUOTA = 1 MB
+DATABASE = sqlite
+
+[transport]
+PLUGINS = tcp
+DEBUG = NO
+ACCEPT_FROM6 = ::1;
+ACCEPT_FROM = 127.0.0.1;
+NEIGHBOUR_LIMIT = 50
+PORT = 12365
+
+[ats]
+WAN_QUOTA_OUT = 3932160
+WAN_QUOTA_IN = 3932160
+
+[core]
+PORT = 12092
+
+[arm]
+DEFAULTSERVICES = core lockmanager
+PORT = 12366
+DEBUG = NO
+
+[transport-tcp]
+TIMEOUT = 300 s
+PORT = 12368
+
+[TESTING]
+NUM_PEERS = 5
+WEAKRANDOM = YES
+DEBUG = YES
+HOSTKEYSFILE = ../../contrib/testing_hostkeys.dat
+MAX_CONCURRENT_SSH = 10
+USE_PROGRESSBARS = YES
+PEERGROUP_TIMEOUT = 2400 s
+
+[gnunetd]
+HOSTKEY = $SERVICEHOME/.hostkey
+
+[PATHS]
+DEFAULTCONFIG = test_lockmanager_api.conf
+SERVICEHOME = /tmp/test-lockmanager/
+
+[dns]
+AUTOSTART = NO
+
+[nse]
+AUTOSTART = NO
diff --git a/src/lockmanager/test_lockmanager_api_lockrelease.c b/src/lockmanager/test_lockmanager_api_lockrelease.c
new file mode 100644
index 0000000..7e24d10
--- /dev/null
+++ b/src/lockmanager/test_lockmanager_api_lockrelease.c
@@ -0,0 +1,301 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file lockmanager/test_lockmanager_api_lockrelease.c
+ * @brief Test cases for lockmanager_api where client disconnects abruptly
+ * @author Sree Harsha Totakura
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_lockmanager_service.h"
+
+#define VERBOSE GNUNET_YES
+
+#define VERBOSE_ARM 1
+
+#define LOG(kind,...) \
+ GNUNET_log (kind, __VA_ARGS__)
+
+#define TIME_REL_SECONDS(min) \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min)
+
+/**
+ * Various steps of the test
+ */
+enum Test
+ {
+ /**
+ * Signal test failure
+ */
+ TEST_FAIL,
+
+ /**
+ * Testing just began
+ */
+ TEST_INIT,
+
+ /**
+ * Client 1 has got the lock successfully; Client 2 should try to acquire
+ * the lock now; after some time client 1 has to release the lock
+ */
+ TEST_CLIENT1_LOCK_SUCCESS,
+
+ /**
+ * Client 2 has got the lock; Should release it and call shutdown
+ */
+ TEST_CLIENT2_LOCK_SUCCESS,
+ };
+
+/**
+ * The testing result
+ */
+static enum Test result;
+
+/**
+ * The process id of the GNUNET ARM process
+ */
+static struct GNUNET_OS_Process *arm_pid = NULL;
+
+/**
+ * Configuration Handle
+ */
+static struct GNUNET_CONFIGURATION_Handle *config;
+
+/**
+ * The handle to the lockmanager service
+ */
+static struct GNUNET_LOCKMANAGER_Handle *handle;
+
+/**
+ * A second client handle to the lockmanager service
+ */
+static struct GNUNET_LOCKMANAGER_Handle *handle2;
+
+/**
+ * The locking request
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *request;
+
+/**
+ * The locking request of second client
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *request2;
+
+/**
+ * Abort task identifier
+ */
+static GNUNET_SCHEDULER_TaskIdentifier abort_task_id;
+
+
+/**
+ * Shutdown nicely
+ *
+ * @param cls
+ * @param tc the task context
+ */
+static void
+do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (GNUNET_SCHEDULER_NO_TASK != abort_task_id)
+ {
+ GNUNET_SCHEDULER_cancel (abort_task_id);
+ abort_task_id = GNUNET_SCHEDULER_NO_TASK;
+ }
+
+ GNUNET_LOCKMANAGER_disconnect (handle);
+ GNUNET_LOCKMANAGER_disconnect (handle2);
+ if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Kill gnunet-service-arm manually\n");
+ }
+ GNUNET_OS_process_wait (arm_pid);
+ GNUNET_OS_process_destroy (arm_pid);
+
+ if (NULL != config)
+ GNUNET_CONFIGURATION_destroy (config);
+}
+
+
+/**
+ * Abort
+ *
+ * @param cls
+ * @param tc the task context
+ */
+static void
+do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n");
+ abort_task_id = GNUNET_SCHEDULER_NO_TASK;
+ result = TEST_FAIL;
+ do_shutdown (cls, tc);
+}
+
+
+/**
+ * Callback for lock status changes
+ *
+ * @param cls the handle
+ *
+ * @param domain_name the locking domain of the lock
+ *
+ * @param lock the lock for which this status is relevant
+ *
+ * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully
+ * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost
+ */
+static void
+status_cb (void *cls,
+ const char *domain_name,
+ uint32_t lock,
+ enum GNUNET_LOCKMANAGER_Status status)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Status change callback called on lock: %d of domain: %s\n",
+ lock, domain_name);
+ GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
+ switch (result)
+ {
+ case TEST_INIT:
+ GNUNET_assert (handle == cls);
+ result = TEST_CLIENT1_LOCK_SUCCESS;
+ request2 = GNUNET_LOCKMANAGER_acquire_lock (handle2,
+ "GNUNET_LOCKMANAGER_TESTING",
+ 99,
+ &status_cb,
+ handle2);
+ GNUNET_assert (NULL != request2);
+ GNUNET_LOCKMANAGER_cancel_request (request);
+ request = NULL;
+ break;
+ case TEST_CLIENT1_LOCK_SUCCESS:
+ GNUNET_assert (handle2 == cls);
+ result = TEST_CLIENT2_LOCK_SUCCESS;
+ GNUNET_LOCKMANAGER_cancel_request (request2);
+ GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1),
+ &do_shutdown,
+ NULL);
+ break;
+ default:
+ GNUNET_assert (0); /* We should never reach here */
+ }
+
+}
+
+
+/**
+ * Testing function
+ *
+ * @param cls NULL
+ * @param tc the task context
+ */
+static void
+test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ result = TEST_INIT;
+ handle = GNUNET_LOCKMANAGER_connect (config);
+ GNUNET_assert (NULL != handle);
+ handle2 = GNUNET_LOCKMANAGER_connect (config);
+
+ request = GNUNET_LOCKMANAGER_acquire_lock (handle,
+ "GNUNET_LOCKMANAGER_TESTING",
+ 99,
+ &status_cb,
+ handle);
+ GNUNET_assert (NULL != request);
+ abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10),
+ &do_abort,
+ NULL);
+}
+
+
+/**
+ * Main point of test execution
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n");
+ config = GNUNET_CONFIGURATION_dup (cfg);
+ arm_pid =
+ GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm",
+#if VERBOSE_ARM
+ "-L", "DEBUG",
+#endif
+ "-c", "test_lockmanager_api.conf", NULL);
+
+ GNUNET_assert (NULL != arm_pid);
+ GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (3),
+ &test,
+ NULL);
+}
+
+
+/**
+ * Main function
+ */
+int main (int argc, char **argv)
+{
+ int ret;
+
+ char *const argv2[] = { "test-lockmanager-api-lockrelease",
+ "-c", "test_lockmanager_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ GNUNET_log_setup ("test-lockmanager-api-lockrelease",
+#if VERBOSE
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL);
+
+ ret =
+ GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
+ "test-lockmanager-api-lockrelease",
+ "nohelp", options, &run, NULL);
+
+ if (GNUNET_OK != ret)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n",
+ ret);
+ return 1;
+ }
+ if (TEST_CLIENT2_LOCK_SUCCESS != result)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n");
+ return 1;
+ }
+ LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n");
+ return 0;
+}
diff --git a/src/lockmanager/test_lockmanager_api_servercrash.c b/src/lockmanager/test_lockmanager_api_servercrash.c
new file mode 100644
index 0000000..3fa6418
--- /dev/null
+++ b/src/lockmanager/test_lockmanager_api_servercrash.c
@@ -0,0 +1,326 @@
+/*
+ This file is part of GNUnet.
+ (C) 2012 Christian Grothoff (and other contributing authors)
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 2, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file lockmanager/test_lockmanager_api_servercrash.c
+ * @brief Test cases for lockmanager_api where the server crashes
+ * @author Sree Harsha Totakura
+ */
+
+#include "platform.h"
+#include "gnunet_util_lib.h"
+#include "gnunet_lockmanager_service.h"
+
+#define VERBOSE GNUNET_YES
+
+#define VERBOSE_ARM 1
+
+#define LOG(kind,...) \
+ GNUNET_log (kind, __VA_ARGS__)
+
+#define TIME_REL_SECONDS(min) \
+ GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, min)
+
+/**
+ * Various steps of the test
+ */
+enum Test
+ {
+ /**
+ * Signal test failure
+ */
+ TEST_FAIL,
+
+ /**
+ * Testing just began
+ */
+ TEST_INIT,
+
+ /**
+ * Client 1 has got the lock successfully; Client 2 should try to acquire
+ * the lock now; after some time client 1 has to release the lock
+ */
+ TEST_CLIENT1_LOCK_SUCCESS,
+
+ /**
+ * Client 2 has got the lock; Server should crash now;
+ */
+ TEST_CLIENT2_LOCK_SUCCESS,
+
+ /**
+ * Client 2 should get lock release due to server crash; Should call
+ * shutdown now
+ */
+ TEST_CLIENT2_SERVER_CRASH_SUCCESS
+ };
+
+/**
+ * The testing result
+ */
+static enum Test result;
+
+/**
+ * The process id of the GNUNET ARM process
+ */
+static struct GNUNET_OS_Process *arm_pid = NULL;
+
+/**
+ * Configuration Handle
+ */
+static struct GNUNET_CONFIGURATION_Handle *config;
+
+/**
+ * The handle to the lockmanager service
+ */
+static struct GNUNET_LOCKMANAGER_Handle *handle;
+
+/**
+ * A second client handle to the lockmanager service
+ */
+static struct GNUNET_LOCKMANAGER_Handle *handle2;
+
+/**
+ * The locking request
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *request;
+
+/**
+ * The locking request of second client
+ */
+static struct GNUNET_LOCKMANAGER_LockingRequest *request2;
+
+/**
+ * Abort task identifier
+ */
+static GNUNET_SCHEDULER_TaskIdentifier abort_task_id;
+
+
+/**
+ * Shutdown nicely
+ *
+ * @param cls
+ * @param tc the task context
+ */
+static void
+do_shutdown (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ if (GNUNET_SCHEDULER_NO_TASK != abort_task_id)
+ {
+ GNUNET_SCHEDULER_cancel (abort_task_id);
+ abort_task_id = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if (NULL != handle)
+ GNUNET_LOCKMANAGER_disconnect (handle);
+ if (NULL != handle2)
+ GNUNET_LOCKMANAGER_disconnect (handle2);
+ if (NULL != arm_pid)
+ {
+ if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Kill gnunet-service-arm manually\n");
+ }
+ GNUNET_OS_process_wait (arm_pid);
+ GNUNET_OS_process_destroy (arm_pid);
+ }
+ if (NULL != config)
+ GNUNET_CONFIGURATION_destroy (config);
+}
+
+
+/**
+ * Abort
+ *
+ * @param cls
+ * @param tc the task context
+ */
+static void
+do_abort (void *cls, const const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Aborting test...\n");
+ abort_task_id = GNUNET_SCHEDULER_NO_TASK;
+ result = TEST_FAIL;
+ do_shutdown (cls, tc);
+}
+
+
+/**
+ * Callback for lock status changes
+ *
+ * @param cls the handle
+ *
+ * @param domain_name the locking domain of the lock
+ *
+ * @param lock the lock for which this status is relevant
+ *
+ * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully
+ * acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost
+ */
+static void
+status_cb (void *cls,
+ const char *domain_name,
+ uint32_t lock,
+ enum GNUNET_LOCKMANAGER_Status status)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Status change callback called on lock: %d of domain: %s\n",
+ lock, domain_name);
+ switch (result)
+ {
+ case TEST_INIT:
+ GNUNET_assert (handle == cls);
+ GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
+ result = TEST_CLIENT1_LOCK_SUCCESS;
+ request2 = GNUNET_LOCKMANAGER_acquire_lock (handle2,
+ "GNUNET_LOCKMANAGER_TESTING",
+ 99,
+ &status_cb,
+ handle2);
+ GNUNET_assert (NULL != request2);
+ GNUNET_LOCKMANAGER_cancel_request (request);
+ request = NULL;
+ break;
+ case TEST_CLIENT1_LOCK_SUCCESS:
+ GNUNET_assert (handle2 == cls);
+ GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
+ result = TEST_CLIENT2_LOCK_SUCCESS;
+ /* We should kill the lockmanager process */
+ if (0 != GNUNET_OS_process_kill (arm_pid, SIGTERM))
+ {
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Kill gnunet-service-arm manually\n");
+ }
+ GNUNET_OS_process_wait (arm_pid);
+ GNUNET_OS_process_destroy (arm_pid);
+ arm_pid =NULL;
+ break;
+ case TEST_CLIENT2_LOCK_SUCCESS:
+ GNUNET_assert (handle2 == cls);
+ GNUNET_assert (GNUNET_LOCKMANAGER_RELEASE == status);
+ GNUNET_assert (99 == lock);
+ GNUNET_assert (0 == strcmp (domain_name, "GNUNET_LOCKMANAGER_TESTING"));
+ result = TEST_CLIENT2_SERVER_CRASH_SUCCESS;
+ GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1),
+ &do_shutdown,
+ NULL);
+ break;
+ default:
+ GNUNET_assert (0); /* We should never reach here */
+ }
+
+}
+
+
+/**
+ * Testing function
+ *
+ * @param cls NULL
+ * @param tc the task context
+ */
+static void
+test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ result = TEST_INIT;
+ handle = GNUNET_LOCKMANAGER_connect (config);
+ GNUNET_assert (NULL != handle);
+ handle2 = GNUNET_LOCKMANAGER_connect (config);
+
+ request = GNUNET_LOCKMANAGER_acquire_lock (handle,
+ "GNUNET_LOCKMANAGER_TESTING",
+ 99,
+ &status_cb,
+ handle);
+ GNUNET_assert (NULL != request);
+ abort_task_id = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (10),
+ &do_abort,
+ NULL);
+}
+
+
+/**
+ * Main point of test execution
+ */
+static void
+run (void *cls, char *const *args, const char *cfgfile,
+ const struct GNUNET_CONFIGURATION_Handle *cfg)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Starting test...\n");
+ config = GNUNET_CONFIGURATION_dup (cfg);
+ arm_pid =
+ GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
+ "gnunet-service-arm",
+#if VERBOSE_ARM
+ "-L", "DEBUG",
+#endif
+ "-c", "test_lockmanager_api.conf", NULL);
+
+ GNUNET_assert (NULL != arm_pid);
+ GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (3),
+ &test,
+ NULL);
+}
+
+
+/**
+ * Main function
+ */
+int main (int argc, char **argv)
+{
+ int ret;
+
+ char *const argv2[] = { "test-lockmanager-api-servercrash",
+ "-c", "test_lockmanager_api.conf",
+#if VERBOSE
+ "-L", "DEBUG",
+#endif
+ NULL
+ };
+
+ struct GNUNET_GETOPT_CommandLineOption options[] = {
+ GNUNET_GETOPT_OPTION_END
+ };
+
+ GNUNET_log_setup ("test-lockmanager-api-servercrash",
+#if VERBOSE
+ "DEBUG",
+#else
+ "WARNING",
+#endif
+ NULL);
+
+ ret =
+ GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
+ "test-lockmanager-api-servercrash",
+ "nohelp", options, &run, NULL);
+
+ if (GNUNET_OK != ret)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, "run failed with error code %d\n",
+ ret);
+ return 1;
+ }
+ if (TEST_CLIENT2_SERVER_CRASH_SUCCESS != result)
+ {
+ LOG (GNUNET_ERROR_TYPE_WARNING, "test failed\n");
+ return 1;
+ }
+ LOG (GNUNET_ERROR_TYPE_INFO, "test OK\n");
+ return 0;
+}