[PATCH 2/2] ipc: add non-blocking options to the bmc & bms apps
by Angus Salkeld
so to test blocking IPC
bmc
bms
to test non-blocking IPC
bmc -n
bms -n
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
Conflicts:
tests/bmc.c
---
tests/bmc.c | 55 ++++++++++++++++++++++++++++++++++++++++++-------
tests/bms.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 105 insertions(+), 16 deletions(-)
diff --git a/tests/bmc.c b/tests/bmc.c
index d518e98..165025b 100644
--- a/tests/bmc.c
+++ b/tests/bmc.c
@@ -41,6 +41,8 @@
#include <sys/time.h>
#include <time.h>
+int blocking = 1;
+int verbose = 0;
#define ITERATIONS 10000
static struct timeval tv1, tv2, tv_elapsed;
@@ -112,19 +114,21 @@ static void bmc_send_nozc (unsigned int size)
req_header.id = 0;
req_header.size = sizeof (qb_ipc_request_header_t) + size;
-
+
iov[0].iov_base = &req_header;
iov[0].iov_len = sizeof (qb_ipc_request_header_t);
iov[1].iov_base = buffer;
iov[1].iov_len = size;
repeat_send:
- res = qb_ipcc_msg_send_reply_receive (
- bmc_ipc_handle,
- iov,
- 2,
- &res_header,
- sizeof (qb_ipc_response_header_t));
+ if (blocking) {
+ res = qb_ipcc_msg_send_reply_receive (bmc_ipc_handle,
+ iov, 2,
+ &res_header, sizeof (qb_ipc_response_header_t));
+ } else {
+ res = qb_ipcc_msg_send (bmc_ipc_handle,
+ iov, 2);
+ }
if (res != 0) {
goto repeat_send;
}
@@ -132,10 +136,45 @@ repeat_send:
qb_ipc_request_header_t *global_zcb_buffer;
-int main (void)
+static void show_usage(const char *name)
+{
+ printf("usage: \n");
+ printf("%s <options>\n", name);
+ printf("\n");
+ printf(" options:\n");
+ printf("\n");
+ printf(" -n non-blocking ipc (default blocking)\n");
+ printf(" -v verbose\n");
+ printf(" -h show this help text\n");
+ printf("\n");
+}
+
+int main (int argc, char *argv[])
{
+ const char *options = "nvh";
+ int opt;
int i, j;
+ if (argc == 1) {
+ show_usage (argv[0]);
+ exit(0);
+ }
+ while ((opt = getopt(argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'n': /* non-blocking */
+ blocking = 0;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'h':
+ default:
+ show_usage (argv[0]);
+ exit(0);
+ break;
+ }
+ }
+
bmc_connect();
ops_fp = fopen ("opsec", "w");
diff --git a/tests/bms.c b/tests/bms.c
index feb096a..7c9fd2e 100644
--- a/tests/bms.c
+++ b/tests/bms.c
@@ -59,6 +59,9 @@
#include <qb/qbpoll.h>
#include <qb/qbipcs.h>
+int blocking = 1;
+int verbose = 0;
+
static qb_hdb_handle_t bms_poll_handle;
struct lib_handler {
@@ -76,7 +79,9 @@ static void bms_benchmark_one_fn (void *conn, const void *msg)
{
qb_ipc_response_header_t res;
- qb_ipcs_response_send (conn, &res, sizeof (res));
+ if (blocking) {
+ qb_ipcs_response_send (conn, &res, sizeof (res));
+ }
}
int ii=0;
@@ -164,16 +169,18 @@ static qb_ipcs_handler_fn_lvalue bms_handler_fn_get (unsigned int service, unsig
static int bms_security_valid (int euid, int egid)
{
- printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
if (euid == 0 || egid == 0) {
return (1);
}
+ printf("%s:%d %s NOT VALID!\n", __FILE__, __LINE__, __func__);
return (0);
}
static int bms_service_available (unsigned int service)
{
- printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ if (verbose) {
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ }
return (service < 1);
}
@@ -214,7 +221,9 @@ static int bms_poll_handler_accept (
int revent,
void *context)
{
- printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ if (verbose) {
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ }
return (qb_ipcs_handler_accept (fd, revent, context));
}
@@ -231,7 +240,9 @@ static int bms_poll_handler_dispatch (
static void bms_poll_accept_add (
int fd)
{
- printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ if (verbose) {
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ }
qb_poll_dispatch_add (bms_poll_handle, fd, POLLIN|POLLNVAL, 0, bms_poll_handler_accept);
}
@@ -239,7 +250,9 @@ static void bms_poll_dispatch_add (
int fd,
void *context)
{
- printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ if (verbose) {
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ }
qb_poll_dispatch_add (bms_poll_handle, fd, POLLIN|POLLNVAL, context,
bms_poll_handler_dispatch);
}
@@ -248,7 +261,9 @@ static void bms_poll_dispatch_modify (
int fd,
int events)
{
- printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ if (verbose) {
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ }
qb_poll_dispatch_modify (bms_poll_handle, fd, events,
bms_poll_handler_dispatch);
}
@@ -284,8 +299,43 @@ static void sigusr1_handler (int num)
{
}
-int main (int argc, char **argv)
+static void show_usage(const char *name)
{
+ printf("usage: \n");
+ printf("%s <options>\n", name);
+ printf("\n");
+ printf(" options:\n");
+ printf("\n");
+ printf(" -n non-blocking ipc (default blocking)\n");
+ printf(" -v verbose\n");
+ printf(" -h show this help text\n");
+ printf("\n");
+}
+
+int main (int argc, char *argv[])
+{
+ const char *options = "nvh";
+ int opt;
+
+ if (argc == 1) {
+ show_usage (argv[0]);
+ exit(0);
+ }
+ while ((opt = getopt(argc, argv, options)) != -1) {
+ switch (opt) {
+ case 'n': /* non-blocking */
+ blocking = 0;
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'h':
+ default:
+ show_usage (argv[0]);
+ exit(0);
+ break;
+ }
+ }
signal (SIGUSR1, sigusr1_handler);
bms_poll_handle = qb_poll_create ();
--
1.6.6.1
13 years, 11 months
[PATCH 1/2] ipc: add a non-blocking send function.
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qbipcc.h | 6 ++++++
lib/ipcc.c | 28 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h
index f873b59..39fa5a1 100644
--- a/include/qb/qbipcc.h
+++ b/include/qb/qbipcc.h
@@ -80,6 +80,12 @@ qb_ipcc_dispatch_flow_control_get (
unsigned int *flow_control_state);
extern int32_t
+qb_ipcc_msg_send (
+ qb_hdb_handle_t handle,
+ const struct iovec *iov,
+ unsigned int iov_len);
+
+extern int32_t
qb_ipcc_msg_send_reply_receive (
qb_hdb_handle_t handle,
const struct iovec *iov,
diff --git a/lib/ipcc.c b/lib/ipcc.c
index a21f3f0..bb79673 100644
--- a/lib/ipcc.c
+++ b/lib/ipcc.c
@@ -999,6 +999,34 @@ error_exit:
}
int32_t
+qb_ipcc_msg_send (
+ qb_hdb_handle_t handle,
+ const struct iovec *iov,
+ unsigned int iov_len)
+{
+ int32_t res;
+ struct ipc_instance *ipc_instance;
+
+ res = qb_hdb_handle_get (&ipc_hdb, handle, (void **)&ipc_instance);
+ if (res != 0) {
+ return (res);
+ }
+
+ pthread_mutex_lock (&ipc_instance->mutex);
+
+ res = msg_send (ipc_instance, iov, iov_len);
+ if (res != 0) {
+ goto error_exit;
+ }
+
+error_exit:
+ qb_hdb_handle_put (&ipc_hdb, handle);
+ pthread_mutex_unlock (&ipc_instance->mutex);
+
+ return (res);
+}
+
+int32_t
qb_ipcc_msg_send_reply_receive (
qb_hdb_handle_t handle,
const struct iovec *iov,
--
1.6.6.1
13 years, 11 months
[PATCH 3/3] ipc: add Steve's benchmark test programs
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
tests/Makefile.am | 14 +++
tests/bmc.c | 153 +++++++++++++++++++++++++++
tests/bmcpt.c | 192 ++++++++++++++++++++++++++++++++++
tests/bms.c | 298 +++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 657 insertions(+), 0 deletions(-)
create mode 100644 tests/bmc.c
create mode 100644 tests/bmcpt.c
create mode 100644 tests/bms.c
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 98fa6cf..91e42e4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -28,6 +28,20 @@
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
+noinst_PROGRAMS = bmc bmcpt bms
+
+bmc_SOURCES = bmc.c
+bmc_CFLAGS = -I$(top_srcdir)/include
+bmc_LDADD = -lrt $(top_builddir)/lib/libqbipcc.la $(top_builddir)/lib/libqbpoll.la
+
+bmcpt_SOURCES = bmcpt.c
+bmcpt_CFLAGS = -I$(top_srcdir)/include
+bmcpt_LDADD = -lrt $(top_builddir)/lib/libqbipcc.la $(top_builddir)/lib/libqbpoll.la
+
+bms_SOURCES = bms.c
+bms_CFLAGS = -I$(top_srcdir)/include
+bms_LDADD = -lrt $(top_builddir)/lib/libqbipcs.la $(top_builddir)/lib/libqbpoll.la
+
if HAVE_CHECK
TESTS = check_hash check_plugin
diff --git a/tests/bmc.c b/tests/bmc.c
new file mode 100644
index 0000000..d518e98
--- /dev/null
+++ b/tests/bmc.c
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake(a)redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <qb/qbipcc.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+
+#define ITERATIONS 10000
+
+static struct timeval tv1, tv2, tv_elapsed;
+
+#define timersub(a, b, result) \
+do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+} while (0)
+
+FILE *mbs_fp;
+
+FILE *ops_fp;
+
+static void bm_start (void)
+{
+ gettimeofday (&tv1, NULL);
+}
+
+static void bm_finish (const char *operation, int size)
+{
+ float ops_per_sec;
+ float mbs_per_sec;
+
+ gettimeofday (&tv2, NULL);
+ timersub (&tv2, &tv1, &tv_elapsed);
+
+ ops_per_sec =
+ ((float)ITERATIONS) / (((float)tv_elapsed.tv_sec) + (((float)tv_elapsed.tv_usec) / 1000000.0));
+
+ mbs_per_sec =
+ ((((float)ITERATIONS) * size) / (((float)tv_elapsed.tv_sec) + (((float)tv_elapsed.tv_usec) / 1000000.0))) / (1024.0*1024.0);
+
+
+ fprintf (ops_fp, "%d %9.3f\n", size, ops_per_sec);
+ fflush (ops_fp);
+ fprintf (mbs_fp, "%d %9.3f\n", size, mbs_per_sec);
+ fflush (mbs_fp);
+
+ printf ("write size %d OPs/sec %9.3f ", size, ops_per_sec);
+ printf ("MB/sec %9.3f\n", mbs_per_sec);
+}
+
+qb_hdb_handle_t bmc_ipc_handle;
+
+static void bmc_connect (void)
+{
+ unsigned int res;
+
+ res = qb_ipcc_service_connect ("qb_ipcs_bm",
+ 0,
+ 8192*128,
+ 8192*128,
+ 8192*128,
+ &bmc_ipc_handle);
+}
+
+static char buffer[1024*1024];
+static void bmc_send_nozc (unsigned int size)
+{
+ struct iovec iov[2];
+ qb_ipc_request_header_t req_header;
+ qb_ipc_response_header_t res_header;
+ int res;
+
+ req_header.id = 0;
+ req_header.size = sizeof (qb_ipc_request_header_t) + size;
+
+ iov[0].iov_base = &req_header;
+ iov[0].iov_len = sizeof (qb_ipc_request_header_t);
+ iov[1].iov_base = buffer;
+ iov[1].iov_len = size;
+
+repeat_send:
+ res = qb_ipcc_msg_send_reply_receive (
+ bmc_ipc_handle,
+ iov,
+ 2,
+ &res_header,
+ sizeof (qb_ipc_response_header_t));
+ if (res != 0) {
+ goto repeat_send;
+ }
+}
+
+qb_ipc_request_header_t *global_zcb_buffer;
+
+int main (void)
+{
+ int i, j;
+
+ bmc_connect();
+
+ ops_fp = fopen ("opsec", "w");
+ mbs_fp = fopen ("mbsec", "w");
+
+ for (j = 1; j < 499; j++) {
+ bm_start();
+ for (i = 0; i < ITERATIONS; i++) {
+ bmc_send_nozc (1000 * j);
+ }
+ bm_finish("send_nozc", 1000 * j);
+ }
+ return EXIT_SUCCESS;
+}
+
diff --git a/tests/bmcpt.c b/tests/bmcpt.c
new file mode 100644
index 0000000..850379f
--- /dev/null
+++ b/tests/bmcpt.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake(a)redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <qb/qbipcc.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <signal.h>
+
+#define ITERATIONS 10000000
+
+struct bm_ctx {
+ qb_hdb_handle_t bmc_ipc_handle;
+ struct timeval tv1;
+ struct timeval tv2;
+ struct timeval tv_elapsed;
+ float mbs;
+ int multi;
+ unsigned int counter;
+};
+
+#define timersub(a, b, result) \
+do { \
+ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
+ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
+ if ((result)->tv_usec < 0) { \
+ --(result)->tv_sec; \
+ (result)->tv_usec += 1000000; \
+ } \
+} while (0)
+
+static void bm_start (struct bm_ctx *ctx)
+{
+ gettimeofday (&ctx->tv1, NULL);
+}
+static void bm_finish (struct bm_ctx *ctx, const char *operation, int size)
+{
+ float ops_per_sec;
+ float mbs_per_sec;
+
+ gettimeofday (&ctx->tv2, NULL);
+ timersub (&ctx->tv2, &ctx->tv1, &ctx->tv_elapsed);
+
+ ops_per_sec =
+ ((float)ctx->counter) / (((float)ctx->tv_elapsed.tv_sec) + (((float)ctx->tv_elapsed.tv_usec) / 1000000.0));
+
+ mbs_per_sec =
+ ((((float)ctx->counter) * size) / (((float)ctx->tv_elapsed.tv_sec) + (((float)ctx->tv_elapsed.tv_usec) / 1000000.0))) / (1024.0*1024.0);
+
+
+ ctx->mbs = ops_per_sec;
+}
+
+static void bmc_connect (struct bm_ctx *ctx)
+{
+ unsigned int res;
+
+ res = qb_ipcc_service_connect ("qb_ipcs_bm",
+ 0,
+ 8192*128,
+ 8192*128,
+ 8192*128,
+ &ctx->bmc_ipc_handle);
+}
+
+static void bmc_disconnect (struct bm_ctx *ctx)
+{
+ qb_ipcc_service_disconnect (ctx->bmc_ipc_handle);
+}
+
+static char buffer[1024*1024];
+static void bmc_send_nozc (struct bm_ctx *ctx, unsigned int size)
+{
+ struct iovec iov[2];
+ qb_ipc_request_header_t req_header;
+ qb_ipc_response_header_t res_header;
+ int res;
+
+ req_header.id = 0;
+ req_header.size = sizeof (qb_ipc_request_header_t) + size;
+
+ iov[0].iov_base = &req_header;
+ iov[0].iov_len = sizeof (qb_ipc_request_header_t);
+ iov[1].iov_base = buffer;
+ iov[1].iov_len = size;
+
+repeat_send:
+ res = qb_ipcc_msg_send_reply_receive (
+ ctx->bmc_ipc_handle,
+ iov,
+ 2,
+ &res_header,
+ sizeof (qb_ipc_response_header_t));
+ if (res != 0) {
+ goto repeat_send;
+ }
+}
+
+unsigned int alarm_notice = 0;
+static void sigalrm_handler (int num)
+{
+ alarm_notice = 1;
+}
+
+static void *benchmark (void *ctx) {
+ struct bm_ctx *bm_ctx = (struct bm_ctx *)ctx;
+
+ bmc_connect(bm_ctx);
+
+ bm_start(bm_ctx);
+ for (;;) {
+ bm_ctx->counter++;
+ bmc_send_nozc (bm_ctx, 1000 * bm_ctx->multi);
+ if (alarm_notice) {
+ bm_finish (bm_ctx, "send_nozc", 1000 * bm_ctx->multi);
+ bmc_disconnect (bm_ctx);
+ return (NULL);
+ }
+ }
+}
+
+#define THREADS 4
+
+int main (void)
+{
+ struct bm_ctx bm_ctx[THREADS];
+ pthread_t threads[THREADS];
+ pthread_attr_t thread_attr[THREADS];
+ int i, j;
+ float total_mbs;
+ void *retval;
+
+
+ signal (SIGALRM, sigalrm_handler);
+ for (j = 0 ; j < 500; j++) {
+ alarm_notice = 0;
+ alarm (3);
+ for (i = 0; i < THREADS; i++) {
+ bm_ctx[i].multi = j + 100;
+ bm_ctx[i].counter = 0;
+ pthread_attr_init (&thread_attr[i]);
+
+ pthread_attr_setdetachstate (&thread_attr[i], PTHREAD_CREATE_JOINABLE);
+ pthread_create (&threads[i], &thread_attr[i], benchmark, &bm_ctx[i]);
+ }
+ for (i = 0; i < THREADS; i++) {
+ pthread_join (threads[i], &retval);
+ }
+ total_mbs = 0;
+ for (i = 0; i < THREADS; i++) {
+ total_mbs = total_mbs + bm_ctx[i].mbs;
+ }
+ printf ("%d ", 1000 * bm_ctx[0].multi);
+ printf ("%9.3f\n", total_mbs);
+ }
+ return EXIT_SUCCESS;
+}
diff --git a/tests/bms.c b/tests/bms.c
new file mode 100644
index 0000000..feb096a
--- /dev/null
+++ b/tests/bms.c
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2002-2006 MontaVista Software, Inc.
+ * Copyright (c) 2006-2009 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake (sdake(a)redhat.com)
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <pthread.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/poll.h>
+#include <sys/uio.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <signal.h>
+#include <sched.h>
+#include <time.h>
+#include <stdarg.h>
+#include <sched.h>
+
+#include <qb/qbpoll.h>
+#include <qb/qbipcs.h>
+
+static qb_hdb_handle_t bms_poll_handle;
+
+struct lib_handler {
+ void (*lib_handler_fn) (void *conn, const void *msg);
+};
+
+struct service_engine {
+ unsigned int private_data_size;
+ int (*lib_init_fn) (void *conn);
+ int (*lib_exit_fn) (void *conn);
+ struct lib_handler *lib_engine;
+};
+
+static void bms_benchmark_one_fn (void *conn, const void *msg)
+{
+ qb_ipc_response_header_t res;
+
+ qb_ipcs_response_send (conn, &res, sizeof (res));
+}
+
+int ii=0;
+static void bms_benchmark_two_fn (void *conn, const void *msg)
+{
+ const qb_ipc_request_header_t *req = msg;
+ const char *req_buf = (char*)msg + sizeof (qb_ipc_request_header_t);
+ qb_ipc_response_header_t res_done;
+
+ qb_ipc_response_header_t res;
+ struct iovec iovec[2];
+
+ res.size = req->size - sizeof (qb_ipc_request_header_t) + sizeof (qb_ipc_response_header_t);
+ res.error = 0;
+ iovec[0].iov_base = &res;
+ iovec[0].iov_len = sizeof (res);
+ iovec[1].iov_base = (void *)req_buf;
+ iovec[1].iov_len = req->size - sizeof (qb_ipc_request_header_t);
+
+ qb_ipcs_dispatch_iov_send (conn, iovec, 2);
+ res_done.size = sizeof (qb_ipc_response_header_t);
+ res_done.error = 0;
+ qb_ipcs_response_send (conn, &res_done, sizeof (res_done));
+}
+
+static int bms_lib_init_fn (void *conn)
+{
+ return (0);
+}
+
+static int bms_lib_exit_fn (void *conn)
+{
+ return (0);
+}
+
+static struct lib_handler bms_lib_engine_one[] = {
+ { /* entry 0 */
+ .lib_handler_fn = bms_benchmark_one_fn,
+ },
+ { /* entry 0 */
+ .lib_handler_fn = bms_benchmark_two_fn,
+ }
+};
+
+static struct service_engine services[1] = {
+ {
+ .private_data_size = 0,
+ .lib_init_fn = bms_lib_init_fn,
+ .lib_exit_fn = bms_lib_exit_fn,
+ .lib_engine = bms_lib_engine_one,
+ }
+};
+
+static void bms_serialize_lock (void)
+{
+}
+
+static void bms_serialize_unlock (void)
+{
+}
+
+/*
+ * Provides the glue from bms to the IPC Service
+ */
+static int bms_private_data_size_get (unsigned int service)
+{
+ return (services[service].private_data_size);
+}
+
+static qb_ipcs_init_fn_lvalue bms_init_fn_get (unsigned int service)
+{
+ return (services[service].lib_init_fn);
+}
+
+static qb_ipcs_exit_fn_lvalue bms_exit_fn_get (unsigned int service)
+{
+ return (services[service].lib_exit_fn);
+}
+
+static qb_ipcs_handler_fn_lvalue bms_handler_fn_get (unsigned int service, unsigned int id)
+{
+ return (services[service].lib_engine[id].lib_handler_fn);
+}
+
+
+static int bms_security_valid (int euid, int egid)
+{
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ if (euid == 0 || egid == 0) {
+ return (1);
+ }
+ return (0);
+}
+
+static int bms_service_available (unsigned int service)
+{
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ return (service < 1);
+}
+
+static int bms_sending_allowed (
+ unsigned int service,
+ unsigned int id,
+ const void *msg,
+ void *sending_allowed_private_data)
+{
+ return (1);
+}
+
+static void bms_sending_allowed_release (void *sending_allowed_private_data)
+{
+}
+
+static void ipc_log_printf (const char *format, ...) __attribute__((format(printf, 1, 2)));
+static void ipc_log_printf (const char *format, ...)
+{
+ va_list ap;
+
+ va_start (ap, format);
+
+ vfprintf (stderr, format, ap);
+
+ va_end (ap);
+}
+
+static void ipc_fatal_error (const char *error_msg)
+{
+ printf ("FATAL Error: %s\n", error_msg);
+ exit (1);
+}
+
+static int bms_poll_handler_accept (
+ qb_hdb_handle_t handle,
+ int fd,
+ int revent,
+ void *context)
+{
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ return (qb_ipcs_handler_accept (fd, revent, context));
+}
+
+static int bms_poll_handler_dispatch (
+ qb_hdb_handle_t handle,
+ int fd,
+ int revent,
+ void *context)
+{
+ return (qb_ipcs_handler_dispatch (fd, revent, context));
+}
+
+
+static void bms_poll_accept_add (
+ int fd)
+{
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ qb_poll_dispatch_add (bms_poll_handle, fd, POLLIN|POLLNVAL, 0, bms_poll_handler_accept);
+}
+
+static void bms_poll_dispatch_add (
+ int fd,
+ void *context)
+{
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ qb_poll_dispatch_add (bms_poll_handle, fd, POLLIN|POLLNVAL, context,
+ bms_poll_handler_dispatch);
+}
+
+static void bms_poll_dispatch_modify (
+ int fd,
+ int events)
+{
+ printf("%s:%d %s\n", __FILE__, __LINE__, __func__);
+ qb_poll_dispatch_modify (bms_poll_handle, fd, events,
+ bms_poll_handler_dispatch);
+}
+
+struct sched_param sched_param = {
+ .sched_priority = 99,
+};
+
+struct qb_ipcs_init_state ipc_init_state = {
+ .socket_name = "qb_ipcs_bm",
+ .sched_policy = 0,
+ .sched_param = NULL,
+ .malloc = malloc,
+ .free = free,
+ .log_printf = ipc_log_printf,
+ .fatal_error = ipc_fatal_error,
+ .security_valid = bms_security_valid,
+ .service_available = bms_service_available,
+ .private_data_size_get = bms_private_data_size_get,
+ .serialize_lock = bms_serialize_lock,
+ .serialize_unlock = bms_serialize_unlock,
+ .sending_allowed = bms_sending_allowed,
+ .sending_allowed_release = bms_sending_allowed_release,
+ .poll_accept_add = bms_poll_accept_add,
+ .poll_dispatch_add = bms_poll_dispatch_add,
+ .poll_dispatch_modify = bms_poll_dispatch_modify,
+ .init_fn_get = bms_init_fn_get,
+ .exit_fn_get = bms_exit_fn_get,
+ .handler_fn_get = bms_handler_fn_get
+};
+
+static void sigusr1_handler (int num)
+{
+}
+
+int main (int argc, char **argv)
+{
+ signal (SIGUSR1, sigusr1_handler);
+
+ bms_poll_handle = qb_poll_create ();
+
+ qb_ipcs_ipc_init (&ipc_init_state);
+
+ qb_poll_run (bms_poll_handle);
+
+ return EXIT_SUCCESS;
+}
--
1.6.6.1
13 years, 11 months
[PATCH 2/3] ipc: add common types to qbipc_common.h
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qbipc_common.h | 49 +++++++++++++++++++++++++++++++++++++++++++++
include/qb/qbipcc.h | 1 +
include/qb/qbipcs.h | 2 +-
lib/ipc_int.h | 11 ----------
lib/ipcs.c | 2 +-
5 files changed, 52 insertions(+), 13 deletions(-)
create mode 100644 include/qb/qbipc_common.h
diff --git a/include/qb/qbipc_common.h b/include/qb/qbipc_common.h
new file mode 100644
index 0000000..2d88b5e
--- /dev/null
+++ b/include/qb/qbipc_common.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Angus Salkeld <asalkeld(a)redhat.com>
+ *
+ * This software licensed under BSD license, the text of which follows:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * - Neither the name of the MontaVista Software, Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef QB_IPC_COMMON_H_DEFINED
+#define QB_IPC_COMMON_H_DEFINED
+
+typedef struct {
+ int size __attribute__((aligned(8)));
+ int id __attribute__((aligned(8)));
+} qb_ipc_request_header_t __attribute__((aligned(8)));
+
+typedef struct {
+ int size __attribute__((aligned(8)));
+ int id __attribute__((aligned(8)));
+ int32_t error __attribute__((aligned(8)));
+} qb_ipc_response_header_t __attribute__((aligned(8)));
+
+#endif /* QB_IPC_COMMON_H_DEFINED */
+
diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h
index 721afee..f873b59 100644
--- a/include/qb/qbipcc.h
+++ b/include/qb/qbipcc.h
@@ -40,6 +40,7 @@
#include <sys/poll.h>
#include <sys/socket.h>
#include <qb/qbhdb.h>
+#include <qb/qbipc_common.h>
#ifdef __cplusplus
extern "C" {
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h
index 1d7ab32..0500db4 100644
--- a/include/qb/qbipcs.h
+++ b/include/qb/qbipcs.h
@@ -36,7 +36,7 @@
#define QB_IPCS_H_DEFINED
#include <stdlib.h>
-//#include <qb/engine/objdb.h>
+#include <qb/qbipc_common.h>
#ifdef __cplusplus
extern "C" {
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
index ecca917..2ce02c7 100644
--- a/lib/ipc_int.h
+++ b/lib/ipc_int.h
@@ -67,17 +67,6 @@ enum req_init_types {
#define MESSAGE_RES_ENABLE_FLOWCONTROL 2
#define MESSAGE_RES_OUTQ_FLUSH_NR 3
-typedef struct {
- int size __attribute__((aligned(8)));
- int id __attribute__((aligned(8)));
-} qb_ipc_request_header_t __attribute__((aligned(8)));
-
-typedef struct {
- int size __attribute__((aligned(8)));
- int id __attribute__((aligned(8)));
- int32_t error __attribute__((aligned(8)));
-} qb_ipc_response_header_t __attribute__((aligned(8)));
-
struct control_buffer {
unsigned int read;
unsigned int write;
diff --git a/lib/ipcs.c b/lib/ipcs.c
index 70ee812..8ad991d 100644
--- a/lib/ipcs.c
+++ b/lib/ipcs.c
@@ -48,8 +48,8 @@
#include <qb/qblist.h>
#include <qb/qbhdb.h>
-#include "ipc_int.h"
#include <qb/qbipcs.h>
+#include "ipc_int.h"
//#define LOGSYS_UTILS_ONLY 1
#include <syslog.h>
--
1.6.6.1
13 years, 11 months
[PATCH 1/3] ipc: remove uneccessary version compatibilty code
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qbipcs.h | 32 +--------------------------
lib/ipcs.c | 60 +++++++-------------------------------------------
2 files changed, 10 insertions(+), 82 deletions(-)
diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h
index 55b6237..1d7ab32 100644
--- a/include/qb/qbipcs.h
+++ b/include/qb/qbipcs.h
@@ -54,33 +54,6 @@ struct qb_ipcs_init_state {
const struct sched_param *sched_param;
void *(*malloc) (size_t size);
void (*free) (void *ptr);
- void (*log_printf) (
- const char *format,
- ...) __attribute__((format(printf, 1, 2)));
- int (*service_available)(unsigned int service);
- int (*private_data_size_get)(unsigned int service);
- int (*security_valid)(int uid, int gid);
- void (*serialize_lock)(void);
- void (*serialize_unlock)(void);
- int (*sending_allowed)(unsigned int service, unsigned int id,
- const void *msg, void *sending_allowed_private_data);
- void (*sending_allowed_release)(void *sending_allowed_private_data);
- void (*poll_accept_add)(int fd);
- void (*poll_dispatch_add)(int fd, void *context);
- void (*poll_dispatch_modify)(int fd, int events);
- void (*poll_dispatch_destroy)(int fd, void *context);
- void (*fatal_error)(const char *error_msg);
- qb_ipcs_init_fn_lvalue (*init_fn_get)(unsigned int service);
- qb_ipcs_exit_fn_lvalue (*exit_fn_get)(unsigned int service);
- qb_ipcs_handler_fn_lvalue (*handler_fn_get)(unsigned int service, unsigned int id);
-};
-
-struct qb_ipcs_init_state_v2 {
- const char *socket_name;
- int sched_policy;
- const struct sched_param *sched_param;
- void *(*malloc) (size_t size);
- void (*free) (void *ptr);
void (*old_log_printf) (
const char *format,
...) __attribute__((format(printf, 1, 2)));
@@ -119,10 +92,7 @@ struct qb_ipcs_init_state_v2 {
};
extern void qb_ipcs_ipc_init (
- struct qb_ipcs_init_state *init_state);
-
-extern void qb_ipcs_ipc_init_v2 (
- struct qb_ipcs_init_state_v2 *init_state_v2);
+ struct qb_ipcs_init_state *init_state);
extern void *qb_ipcs_private_data_get (void *conn);
diff --git a/lib/ipcs.c b/lib/ipcs.c
index 7a69047..70ee812 100644
--- a/lib/ipcs.c
+++ b/lib/ipcs.c
@@ -70,7 +70,7 @@
#define MSG_SEND_LOCKED 0
#define MSG_SEND_UNLOCKED 1
-static struct qb_ipcs_init_state_v2 *api = NULL;
+static struct qb_ipcs_init_state *api = NULL;
QB_DECLARE_LIST_INIT (conn_info_qb_list_head);
@@ -154,8 +154,6 @@ static void ipc_disconnect (struct conn_info *conn_info);
static void msg_send (void *conn, const struct iovec *iov, unsigned int iov_len,
int locked);
-static void _qb_ipc_init(void);
-
#define log_printf(level, format, args...) \
do { \
api->log_printf ( level, \
@@ -667,7 +665,7 @@ retry_semop:
qb_ipcs_response_send (conn_info,
&qb_ipc_response_header,
sizeof (qb_ipc_response_header_t));
- } else
+ } else
if (send_ok) {
api->serialize_lock();
api->stats_increment_value (conn_info->stats_handle, "requests");
@@ -905,59 +903,19 @@ static int conn_info_create (int fd)
/*
* Exported functions
*/
-extern void qb_ipcs_ipc_init_v2 (
- struct qb_ipcs_init_state_v2 *init_state_v2)
-{
- api = init_state_v2;
- api->old_log_printf = NULL;
-
- log_printf (LOG_DEBUG, "you are using ipc api v2\n");
- _qb_ipc_init ();
-}
-
extern void qb_ipcs_ipc_init (
- struct qb_ipcs_init_state *init_state)
+ struct qb_ipcs_init_state *init_state)
{
- api = calloc (sizeof(struct qb_ipcs_init_state_v2), 1);
- /* v2 api */
+ int server_fd;
+ struct sockaddr_un un_addr;
+ int res;
+
+ api = init_state;
+ api->old_log_printf = NULL;
api->stats_create_connection = dummy_stats_create_connection;
api->stats_destroy_connection = dummy_stats_destroy_connection;
api->stats_update_value = dummy_stats_update_value;
api->stats_increment_value = dummy_stats_increment_value;
- api->log_printf = NULL;
-
- /* v1 api */
- api->socket_name = init_state->socket_name;
- api->sched_policy = init_state->sched_policy;
- api->sched_param = init_state->sched_param;
- api->malloc = init_state->malloc;
- api->free = init_state->free;
- api->old_log_printf = init_state->log_printf;
- api->fatal_error = init_state->fatal_error;
- api->security_valid = init_state->security_valid;
- api->service_available = init_state->service_available;
- api->private_data_size_get = init_state->private_data_size_get;
- api->serialize_lock = init_state->serialize_lock;
- api->serialize_unlock = init_state->serialize_unlock;
- api->sending_allowed = init_state->sending_allowed;
- api->sending_allowed_release = init_state->sending_allowed_release;
- api->poll_accept_add = init_state->poll_accept_add;
- api->poll_dispatch_add = init_state->poll_dispatch_add;
- api->poll_dispatch_modify = init_state->poll_dispatch_modify;
- api->init_fn_get = init_state->init_fn_get;
- api->exit_fn_get = init_state->exit_fn_get;
- api->handler_fn_get = init_state->handler_fn_get;
-
- log_printf (LOG_DEBUG, "you are using ipc api v1\n");
-
- _qb_ipc_init ();
-}
-
-static void _qb_ipc_init(void)
-{
- int server_fd;
- struct sockaddr_un un_addr;
- int res;
/*
* Create socket for IPC clients, name socket, listen for connections
--
1.6.6.1
13 years, 11 months
Pointers or Handles?
by Angus Salkeld
Hi
In looking to improve the usability of libqb functions (mainly ipc client & server functions).
I started looking at the way glib & dbus do it.
GMainLoop * g_main_loop_new (GMainContext *context,
gboolean is_running);
GMainContext * g_main_context_new (void);
GSource * g_timeout_source_new (guint interval);
glib describes these returned types as "opaque". You can't do anything to them directly.
DBusConnection * dbus_connection_open (const char *address, DBusError *error);
dbus says: "All fields are private."
So the returned type has no real value to the user - it is just a pointer you have to use.
Both glib and dbus provide reference and dereference functions to prevent these pointers
from been freed by other code (in another thread). They use atomic inc & dec functions.
The current API of corosync is "inherited" from the AIS API.
This looks like:
a_handle_t handle;
res = something_create (args ..., &handle);
...
res = something_get (handle, ...);
...
something_destroy (handle);
Here handles are like file handles to represent an object. Every time you
open/create an "object", it has a reference count incremented.
So both take care of reference counting but if you have an old pointer/handle
to a destroyed object then the pointer method would result in a crash if you
dereferenced it where as the handle method would result in a "bad handle"
error code.
Which is better?.
1)
The pointer API seems to be a little more friendly/obvious to me.
Also it is typed in that you will get a compiler error if you pass GSource*
into a function expecting a GMainLoop* argument (although this could be done with handles too).
2)
The handle seems a little safer if you have old/stale references.
3)
It is also good to be "like the others" in terms of familiarity to developers (easy of use).
Are there any other arguments for either type of API?
Another question is the way return codes are returned:
1)
APointer* obj;
SomeStatus ret;
obj = xyz_create("something", &ret);
if (!obj) {
xyz_print_error(ret);
return;
}
2)
a_handle_t handle;
int ret;
ret = xyz_create ("something", &handle);
if (ret != 0) {
perror (ret);
return;
}
Any opinions on these?
Basically the question is:
Do we follow posix API or libraries like glib/libevent/dbus?
I am leaning towards the "glib/libevent/dbus" style API as libqb
is at a similar layer. We are providing higher layer functionality
on top of a posix API.
-Angus
13 years, 11 months
[PATCH] check_plugin: Add -rdynamic to check program
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
tests/Makefile.am | 1 +
tests/check_plugin.c | 4 ++--
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b269d88..98fa6cf 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -41,6 +41,7 @@ check_hash_LDADD = $(top_builddir)/lib/libqbhash.la @CHECK_LIBS@
check_plugin_SOURCES = check_plugin.c
check_plugin_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
check_plugin_LDADD = $(top_builddir)/lib/libqbplugin.a @CHECK_LIBS@
+check_plugin_LDFLAGS = $(OS_DYFLAGS)
noinst_libdir = $(shell pwd)/$(top_builddir)/tests
diff --git a/tests/check_plugin.c b/tests/check_plugin.c
index 327adc9..af83c36 100644
--- a/tests/check_plugin.c
+++ b/tests/check_plugin.c
@@ -130,7 +130,7 @@ START_TEST (test_plugin)
}
END_TEST
-static Suite *hash_suite (void)
+static Suite *plugin_suite (void)
{
TCase *tc_plugin;
Suite *s = suite_create ("plugin");
@@ -145,7 +145,7 @@ int main (void)
{
int number_failed;
- Suite *s = hash_suite ();
+ Suite *s = plugin_suite ();
SRunner *sr = srunner_create (s);
srunner_run_all (sr, CK_NORMAL);
number_failed = srunner_ntests_failed (sr);
--
1.6.6.1
13 years, 11 months
[PATCH 2/2] check_hash: fix test must be run in one test case.
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
tests/check_hash.c | 68 ++++++++++++---------------------------------------
1 files changed, 16 insertions(+), 52 deletions(-)
diff --git a/tests/check_hash.c b/tests/check_hash.c
index 19bc28d..1bbbdd2 100644
--- a/tests/check_hash.c
+++ b/tests/check_hash.c
@@ -36,52 +36,34 @@
#include <check.h>
#include <qb/qbhash.h>
-qb_hdb_handle_t handle;
-unsigned int distribution[65536];
-
-
-START_TEST (test_hash_init)
-{
- int res;
- handle = 0;
-
- res = qb_hash_initialize (&handle, 3, 17);
-
- ck_assert_int_ne (handle, 0);
- ck_assert_int_eq (res, 0);
-
- memset (distribution, 0, sizeof (distribution));
-}
-END_TEST
START_TEST (test_hash_load)
{
char word[1000];
FILE *fp;
- int hashes_done = 0;
+ int res = 0;
+ qb_hdb_handle_t handle = 0;
+ void *value;
+ uint64_t value_len;
+ res = qb_hash_initialize (&handle, 17, 0);
+
+ ck_assert_int_ne (handle, 0);
+ ck_assert_int_eq (res, 0);
/*
* Load hash table with dictionary
*/
fp = fopen ("/usr/share/dict/words", "r");
while (fgets (word, sizeof (word), fp)) {
word[strlen (word) - 1] = '\0';
- qb_hash_key_set (handle, word, word, strlen (word) + 1);
- hashes_done += 1;
+ res = qb_hash_key_set (handle, word, word, strlen (word) + 1);
+ //if (res < 0) {
+ // printf ("FAILED to insert %s : %s\n", word, strerror(errno));
+ //}
+ ck_assert_int_eq (res, 0);
}
fclose (fp);
- fail_unless (1 == 1);
-}
-END_TEST
-
-START_TEST (test_hash_verify)
-{
- char word[1000];
- FILE *fp;
- void *value;
- uint64_t value_len;
-
/*
* Verify dictionary produces correct values
*/
@@ -92,14 +74,6 @@ START_TEST (test_hash_verify)
ck_assert_str_eq (word, value);
}
fclose (fp);
-}
-END_TEST
-
-START_TEST (test_hash_delete)
-{
- char word[1000];
- FILE *fp;
- int res;
/*
* Delete all dictionary entries
@@ -111,30 +85,20 @@ START_TEST (test_hash_delete)
ck_assert_int_eq (res, 0);
}
fclose (fp);
-
}
END_TEST
+
static Suite *hash_suite (void)
{
TCase *tc_load;
- TCase *tc_verify;
- TCase *tc_delete;
Suite *s = suite_create ("hashtable");
- tc_load = tcase_create ("load");
- tcase_add_test (tc_load, test_hash_init);
+ tc_load = tcase_create ("load_and_verify");
tcase_add_test (tc_load, test_hash_load);
+ tcase_set_timeout(tc_load, 10);
suite_add_tcase (s, tc_load);
- tc_verify = tcase_create ("verify");
- tcase_add_test (tc_verify, test_hash_verify);
- suite_add_tcase (s, tc_verify);
-
- tc_delete = tcase_create ("delete");
- tcase_add_test (tc_delete, test_hash_delete);
- suite_add_tcase (s, tc_delete);
-
return s;
}
--
1.6.6.1
13 years, 11 months
[PATCH 1/2] hash: improve the error handling in key_set()
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
lib/hash.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/hash.c b/lib/hash.c
index 93d27bc..38b15bb 100644
--- a/lib/hash.c
+++ b/lib/hash.c
@@ -134,7 +134,7 @@ int32_t qb_hash_key_set (
struct qb_list_head *list;
int found = 0;
struct hash_node *hash_node;
- int res;
+ int res = 0;
res = qb_hdb_handle_get (&qb_hash_handle_db, handle, (void *)&hash_table);
if (res != 0) {
@@ -158,6 +158,8 @@ int32_t qb_hash_key_set (
if (found == 0) {
hash_node = malloc (sizeof (struct hash_node) + strlen (key) + 1);
if (hash_node == 0) {
+ res = -1;
+ errno = -ENOMEM;
goto error_exit;
}
@@ -183,7 +185,7 @@ error_exit:
pthread_mutex_unlock (&hash_table->hash_buckets[hash_entry].mutex);
qb_hdb_handle_put (&qb_hash_handle_db, handle);
- return (0);
+ return (res);
}
--
1.6.6.1
13 years, 11 months