[PATCH 1/2] Fix ./check -h output
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
check | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/check b/check
index 2611e82..0fa81bb 100755
--- a/check
+++ b/check
@@ -22,7 +22,7 @@ help_all() {
echo " mock Test doing a mock build"
echo " coverity Run coverity"
echo " abi Check abi compatibility"
- echo " api api sanity test"
+ echo " api_sanity api sanity test"
echo
echo " help This help"
echo
--
1.7.7.4
12 years, 4 months
[PATCH] map: free unused leaf nodes
by Angus Salkeld
So if a node has no children and no value or notifier
then it is freed.
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
lib/trie.c | 24 +++++++++++++++++++++++-
tests/check_map.c | 7 +++++--
2 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/lib/trie.c b/lib/trie.c
index 62761cf..9561b99 100644
--- a/lib/trie.c
+++ b/lib/trie.c
@@ -333,6 +333,26 @@ trie_lookup(struct trie *t, const char *key, int exact_match)
}
static void
+trie_node_release(struct trie *t, struct trie_node *node)
+{
+ if (node->num_children == 0 &&
+ node->refcount == 0 &&
+ node->parent != NULL &&
+ qb_list_empty(&node->notifier_head)) {
+ struct trie_node *p = node->parent;
+ /*
+ * unlink the node from the parent
+ */
+ p->children[node->idx] = NULL;
+ free(node);
+ t->num_nodes--;
+ t->mem_used -= sizeof(struct trie_node);
+
+ trie_node_release(t, p);
+ }
+}
+
+static void
trie_node_destroy(struct trie *t, struct trie_node *n)
{
if (n->value == NULL) {
@@ -342,6 +362,8 @@ trie_node_destroy(struct trie *t, struct trie_node *n)
n->key = NULL;
n->value = NULL;
+
+ trie_node_release(t, n);
}
static void
@@ -367,7 +389,6 @@ trie_print_node(struct trie_node *n, struct trie_node *r, const char *suffix)
}
}
-
static void
trie_node_ref(struct trie *t, struct trie_node *node)
{
@@ -628,6 +649,7 @@ trie_notify_del(qb_map_t * m, const char *key,
}
}
if (found) {
+ trie_node_release(t, n);
return 0;
} else {
return -ENOENT;
diff --git a/tests/check_map.c b/tests/check_map.c
index 50c6317..23f005e 100644
--- a/tests/check_map.c
+++ b/tests/check_map.c
@@ -97,15 +97,18 @@ static int32_t
check_order(const char *key, void *value, void *data)
{
int *o = (int*)data;
- ck_assert(chars[*o][0] == key[0]);
+ ck_assert_str_eq(chars[*o], key);
+ ck_assert_str_eq(chars[*o], value);
(*o)++;
return QB_FALSE;
}
+
static int32_t
check_order2(const char *key, void *value, void *data)
{
int *o = (int*)data;
- ck_assert(chars2[*o][0] == key[0]);
+ ck_assert_str_eq(chars2[*o], key);
+ ck_assert_str_eq(chars2[*o], value);
(*o)++;
return QB_FALSE;
}
--
1.7.7.4
12 years, 4 months
[PATCH] Allow the array to automatically grow.
by Angus Salkeld
this makes it a bit friendlier to use, as
the user will not have to call qb_array_grow().
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
examples/ipcserver.c | 6 +-----
include/qb/qbarray.h | 23 +++++++++++++++++++++++
lib/array.c | 26 +++++++++++++++++++++++++-
lib/log_dcs.c | 8 ++------
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/examples/ipcserver.c b/examples/ipcserver.c
index 4a51121..21d5013 100644
--- a/examples/ipcserver.c
+++ b/examples/ipcserver.c
@@ -173,10 +173,6 @@ my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts,
GIOChannel *channel;
int32_t res = 0;
- res = qb_array_grow(gio_map, fd + 1);
- if (res < 0) {
- return res;
- }
res = qb_array_index(gio_map, fd, (void**)&adaptor);
if (res < 0) {
return res;
@@ -320,7 +316,7 @@ main(int32_t argc, char *argv[])
} else {
#ifdef HAVE_GLIB
glib_loop = g_main_loop_new(NULL, FALSE);
- gio_map = qb_array_create(64, sizeof(struct gio_to_qb_poll));
+ gio_map = qb_array_create_2(64, sizeof(struct gio_to_qb_poll), 1);
qb_ipcs_poll_handlers_set(s1, &glib_ph);
qb_ipcs_run(s1);
g_main_loop_run(glib_loop);
diff --git a/include/qb/qbarray.h b/include/qb/qbarray.h
index 99069a5..b969fd3 100644
--- a/include/qb/qbarray.h
+++ b/include/qb/qbarray.h
@@ -36,6 +36,16 @@ extern "C" {
/**
* @file qbarray.h
* This is a dynamic array (it can grow, but without moving memory).
+ *
+ * @code
+ * arr = qb_array_create_2(64, sizeof(struct my_struct), 256);
+ * ...
+ * res = qb_array_index(arr, idx, (void**)&my_ptr);
+ * if (res < 0) {
+ * return res;
+ * }
+ * // use my_ptr, now even if there is a grow, this pointer will be valid.
+ * @endcode
*/
struct qb_array;
@@ -55,6 +65,19 @@ typedef struct qb_array qb_array_t;
qb_array_t* qb_array_create(size_t max_elements, size_t element_size);
/**
+ * Create an array with fixed sized elements.
+ *
+ * @param max_elements initial max elements.
+ * @param element_size size of each element.
+ * @param autogrow_elements the number of elements to grow automatically by.
+ *
+ * @return array instance.
+ */
+qb_array_t* qb_array_create_2(size_t max_elements, size_t element_size,
+ size_t autogrow_elements);
+
+
+/**
* Get an element at a particular index.
* @param a array instance.
* @param idx the index
diff --git a/lib/array.c b/lib/array.c
index 96a7f43..a3a1e5c 100644
--- a/lib/array.c
+++ b/lib/array.c
@@ -33,11 +33,19 @@ struct qb_array {
size_t max_elements;
size_t element_size;
size_t num_bins;
+ size_t autogrow_elements;
};
qb_array_t *
qb_array_create(size_t max_elements, size_t element_size)
{
+ return qb_array_create_2(max_elements, element_size, 0);
+}
+
+qb_array_t *
+qb_array_create_2(size_t max_elements, size_t element_size,
+ size_t autogrow_elements)
+{
int32_t i;
struct qb_array *a = NULL;
@@ -49,6 +57,10 @@ qb_array_create(size_t max_elements, size_t element_size)
errno = -EINVAL;
return NULL;
}
+ if (autogrow_elements > MAX_BIN_ELEMENTS) {
+ errno = -EINVAL;
+ return NULL;
+ }
a = calloc(1, sizeof(struct qb_array));
if (a == NULL) {
return NULL;
@@ -56,6 +68,7 @@ qb_array_create(size_t max_elements, size_t element_size)
a->element_size = element_size;
a->max_elements = max_elements;
a->num_bins = QB_MIN((max_elements / MAX_BIN_ELEMENTS) + 1, MAX_BINS);
+ a->autogrow_elements = autogrow_elements;
for (i = 0; i < MAX_BINS; i++) {
if (i < a->num_bins) {
@@ -77,9 +90,20 @@ qb_array_index(struct qb_array * a, int32_t idx, void **element_out)
if (a == NULL || element_out == NULL) {
return -EINVAL;
}
- if (idx >= a->max_elements || idx < 0) {
+ if (idx < 0) {
return -ERANGE;
}
+ if (idx >= a->max_elements) {
+ elem = idx + a->autogrow_elements;
+ if (a->autogrow_elements == 0) {
+ return -ERANGE;
+ } else {
+ int32_t rc = qb_array_grow(a, elem);
+ if (rc != 0) {
+ return rc;
+ }
+ }
+ }
b = BIN_NUM_GET(idx);
assert(b < a->num_bins);
elem = ELEM_NUM_GET(idx);
diff --git a/lib/log_dcs.c b/lib/log_dcs.c
index 64a8bc4..c5022a5 100644
--- a/lib/log_dcs.c
+++ b/lib/log_dcs.c
@@ -78,8 +78,6 @@ _log_dcs_new_cs(const char *function,
int32_t call_register = QB_FALSE;
if (qb_array_index(callsite_arr, callsite_arr_next, (void **)&cs) < 0) {
- rc = qb_array_grow(callsite_arr, callsite_arr_next + 255);
- assert(rc == 0);
rc = qb_array_index(callsite_arr, callsite_arr_next,
(void **)&cs);
assert(rc == 0);
@@ -128,8 +126,6 @@ qb_log_dcs_get(int32_t * newly_created,
*/
(void)qb_thread_lock(arr_next_lock);
if (rc < 0) {
- rc = qb_array_grow(lookup_arr, lineno + 255);
- assert(rc == 0);
rc = qb_array_index(lookup_arr, lineno, (void **)&csl_head);
assert(rc == 0);
}
@@ -171,8 +167,8 @@ cleanup:
void
qb_log_dcs_init(void)
{
- lookup_arr = qb_array_create(256, sizeof(struct callsite_list));
- callsite_arr = qb_array_create(256, sizeof(struct qb_log_callsite));
+ lookup_arr = qb_array_create_2(256, sizeof(struct callsite_list), 256);
+ callsite_arr = qb_array_create_2(256, sizeof(struct qb_log_callsite), 256);
arr_next_lock = qb_thread_lock_create(QB_THREAD_LOCK_SHORT);
--
1.7.7.4
12 years, 4 months
[PATCH] map: add some introductory doxygen
by Angus Salkeld
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qbmap.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/include/qb/qbmap.h b/include/qb/qbmap.h
index 051a95a..2f1b11a 100644
--- a/include/qb/qbmap.h
+++ b/include/qb/qbmap.h
@@ -31,7 +31,62 @@ extern "C" {
/**
* @file qbmap.h
- * This provides a map interface to a trie, hashtable or skiplist.
+ * This provides a map interface to a Patricia trie, hashtable or skiplist.
+ *
+ * @par Ordering
+ * The hashtable is NOT ordered, but ptrie and skiplist are.
+ *
+ * @par Iterating
+ * Below is a simple example of how to iterate over a map.
+ * @code
+ * const char *p;
+ * void *data;
+ * qb_map_iter_t *it = qb_map_iter_create(m);
+ * for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) {
+ * printf("%s > %s\n", p, (char*) data);
+ * }
+ * qb_map_iter_free(it);
+ * @endcode
+ *
+ * Deletion of items within the iterator is supported. But note do not
+ * free the item memory in the iterator. If you need to free the data
+ * items then register for a notifier and free the memory there. This
+ * is required as the items are reference counted.
+ * @code
+ * qb_map_notify_add(m, NULL, my_map_free_handler,
+ * QB_MAP_NOTIFY_FREE, NULL);
+ * @endcode
+ *
+ * @par Notifications
+ * These allow you to get callbacks when values are inserted/removed or
+ * replaced.
+ * @note hashtable only supports deletion and replacement notificatins.
+ * There is also a special global callback for freeing deleted and replaced
+ * values (QB_MAP_NOTIFY_FREE).
+ * @see qb_map_notify_add() qb_map_notify_del_2()
+ *
+ * @par Prefix matching
+ * The ptrie supports prefixes in the iterator:
+ *
+ * @code
+ * it = qb_map_pref_iter_create(m, "aa");
+ * while ((p = qb_map_iter_next(it, &data)) != NULL) {
+ * printf("%s > %s\n", p, (char*)data);
+ * }
+ * qb_map_iter_free(it);
+ * @endcode
+ *
+ * The ptrie also supports prefixes in notifications:
+ * (remember to pass QB_MAP_NOTIFY_RECURSIVE into the notify_add.
+ * @code
+ * qb_map_notify_add(m, "root", my_map_notification,
+ * (QB_MAP_NOTIFY_INSERTED|
+ * QB_MAP_NOTIFY_DELETED|
+ * QB_MAP_NOTIFY_REPLACED|
+ * QB_MAP_NOTIFY_RECURSIVE),
+ * NULL);
+ *
+ * @endcode
*/
/**
@@ -77,9 +132,12 @@ qb_map_t* qb_hashtable_create(size_t max_size);
qb_map_t* qb_skiplist_create(void);
/**
- * Create a sorted map using a trie or "Prefix list".
+ * Create a sorted map using a Patricia trie or "Radix tree".
*
- * @see en.wikipedia.org/wiki/Trie
+ * @htmlonly
+ * See the wikipedia <a href="http://en.wikipedia.org/wiki/Radix_Tree">Radix_tree</a>
+ * and <a href="http://en.wikipedia.org/wiki/Trie">Trie</a> pages.
+ * @endhtmlonly
*/
qb_map_t* qb_trie_create(void);
--
1.7.7.4
12 years, 4 months
[PATCH] Add a samplewindow API
by Steven Dake
This API works by allowing the API user to keep a list of samples internally.
Every time a new sample is taken, the difference between the current sample
and the first sample in the window is returned. When the sample array is
filled, old entries drop off the sample list.
The use case where this is helpful is recovery escalation. Every time a failure
occurs we take a sample. If the resulting window is less then the escalation
window, an escalation should occur and the sample window should be reset.
Signed-off-by: Steven Dake <sdake(a)redhat.com>
---
include/qb/qbutil.h | 25 +++++++++++++
lib/util.c | 64 ++++++++++++++++++++++++++++++++
tests/Makefile.am | 8 +++-
tests/check_util.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 195 insertions(+), 2 deletions(-)
create mode 100644 tests/check_util.c
diff --git a/include/qb/qbutil.h b/include/qb/qbutil.h
index 2b450e9..d737ec2 100644
--- a/include/qb/qbutil.h
+++ b/include/qb/qbutil.h
@@ -171,6 +171,31 @@ uint64_t qb_util_stopwatch_us_elapsed_get(qb_util_stopwatch_t *sw);
*/
float qb_util_stopwatch_sec_elapsed_get(qb_util_stopwatch_t *sw);
+typedef struct qb_util_samplewindow qb_util_samplewindow_t;
+
+/**
+ * Create a timer sample window
+ */
+qb_util_samplewindow_t * qb_util_samplewindow_create(uint32_t size);
+
+/**
+ * Free a timer sample window
+ */
+void qb_util_samplewindow_free(qb_util_samplewindow_t *sw);
+
+/**
+ * Get the elapsed time in micro seconds across the sample window.
+ *
+ * A return value of 0 indicates there have not been enough samples
+ * to determine the elapsed time.
+ */
+uint64_t qb_util_samplewindow_sample(qb_util_samplewindow_t *sw);
+
+/*
+ * Reset the sample window
+ */
+void qb_util_samplewindow_reset(qb_util_samplewindow_t *sw);
+
/* *INDENT-OFF* */
#ifdef __cplusplus
}
diff --git a/lib/util.c b/lib/util.c
index 51c94bb..d9f11c6 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -272,3 +272,67 @@ qb_util_stopwatch_sec_elapsed_get(qb_util_stopwatch_t * sw)
return ((float)e6 / (float)QB_TIME_US_IN_SEC);
}
+struct qb_util_samplewindow {
+ uint32_t size;
+ uint32_t entries;
+ uint64_t *entry_list;
+};
+
+/**
+ * Create a timer sample window
+ */
+qb_util_samplewindow_t * qb_util_samplewindow_create(uint32_t size)
+{
+ struct qb_util_samplewindow *sw;
+
+ sw = (struct qb_util_samplewindow *)calloc(1, sizeof(struct qb_util_stopwatch));
+ sw->size = size;
+ sw->entry_list = (uint64_t *)calloc(1, sizeof (uint64_t) * size);
+ if (sw->entry_list == NULL) {
+ free (sw);
+ sw = NULL;
+ }
+ return sw;
+}
+
+/**
+ * Free a timer sample window
+ */
+void qb_util_samplewindow_free(qb_util_samplewindow_t *sw)
+{
+ free(sw->entry_list);
+ free(sw);
+}
+
+/**
+ * Get the elapsed time in micro seconds across the sample window.
+ *
+ * A return value of 0 indicates there have not been enough samples
+ * to determine the elapsed time.
+ */
+uint64_t qb_util_samplewindow_sample(qb_util_samplewindow_t *sw)
+{
+ uint32_t new_entry_pos;
+ uint64_t time_start;
+ uint64_t time_end;
+
+ new_entry_pos = sw->entries % (sw->size);
+
+ sw->entry_list[new_entry_pos] = qb_util_nano_current_get();
+ sw->entries++;
+ if (sw->entries < sw->size) {
+ return 0ULL;
+ }
+
+ time_start = sw->entry_list[(new_entry_pos) % sw->size];
+ time_end = sw->entry_list[(new_entry_pos + 1) % sw->size];
+ return (time_start - time_end) / QB_TIME_NS_IN_USEC;
+}
+
+/*
+ * Reset the sample window
+ */
+void qb_util_samplewindow_reset(qb_util_samplewindow_t *sw)
+{
+ sw->entries = 0;
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
index d8f64e2..dd73363 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -73,11 +73,11 @@ bench_log_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la
if HAVE_CHECK
EXTRA_DIST += resources.test
-TESTS = array.test map.test rb.test log.test loop.test ipc.test resources.test
+TESTS = array.test map.test rb.test log.test loop.test ipc.test resources.test util.test
resources.log: rb.log log.log ipc.log
-check_PROGRAMS = array.test map.test rb.test log.test loop.test ipc.test
+check_PROGRAMS = array.test map.test rb.test log.test loop.test ipc.test util.test
check_SCRIPTS = resources.test
array_test_SOURCES = check_array.c $(top_builddir)/include/qb/qbarray.h
@@ -104,6 +104,10 @@ log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h
log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
log_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
+util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h
+util_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include
+util_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@
+
endif
clean-generic:
diff --git a/tests/check_util.c b/tests/check_util.c
new file mode 100644
index 0000000..0313325
--- /dev/null
+++ b/tests/check_util.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * All rights reserved.
+ *
+ * Author: Steven Dake <sdake(a)redhat.com>
+ *
+ * This file is part of libqb.
+ *
+ * libqb is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * libqb is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libqb. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "os_base.h"
+#include <check.h>
+
+#include <qb/qbdefs.h>
+#include <qb/qbutil.h>
+#include <qb/qblog.h>
+
+START_TEST(test_check_samplewindow)
+{
+ qb_util_samplewindow_t *sw;
+ uint64_t res;
+
+ sw = qb_util_samplewindow_create(5);
+ res = qb_util_samplewindow_sample(sw);
+ ck_assert_int_eq(res, 0ULL);
+
+ usleep(10000);
+ res = qb_util_samplewindow_sample(sw);
+ ck_assert_int_eq(res, 0ULL);
+
+ usleep(20000);
+ res = qb_util_samplewindow_sample(sw);
+ ck_assert_int_eq(res, 0ULL);
+
+ usleep(30000);
+ res = qb_util_samplewindow_sample(sw);
+ ck_assert_int_eq(res, 0ULL);
+
+ usleep(40000);
+ res = qb_util_samplewindow_sample(sw);
+ /*
+ * window should be 100000 (40000 + 30000 + 20000 + 10000) usec
+ */
+ ck_assert(res > 95000);
+ ck_assert(res < 105000);
+
+ usleep(50000);
+ res = qb_util_samplewindow_sample(sw);
+ /*
+ * window should be 140000 (50000 + 40000 + 30000 + 20000) usec
+ */
+ ck_assert(res > 135000);
+ ck_assert(res < 145000);
+
+}
+END_TEST
+
+static Suite *util_suite(void)
+{
+ TCase *tc;
+ Suite *s = suite_create("qb_util");
+
+ tc = tcase_create("properop");
+ tcase_add_test(tc, test_check_samplewindow);
+ suite_add_tcase(s, tc);
+
+ return s;
+}
+
+int32_t main(void)
+{
+ int32_t number_failed;
+
+ Suite *s = util_suite();
+ SRunner *sr = srunner_create(s);
+
+ qb_log_init("check", LOG_USER, LOG_EMERG);
+ qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
+ qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+ QB_LOG_FILTER_FILE, "*", LOG_INFO);
+ qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+
+ srunner_run_all(sr, CK_VERBOSE);
+ number_failed = srunner_ntests_failed(sr);
+ srunner_free(sr);
+ return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
--
1.7.7.4
12 years, 4 months
make rpm error of libqb
by nozawat
Hi
Pacemaker depended on libqb.
Therefore I was going to make RPM of libqb.
I got libqb from the following.
->https://github.com/asalkeld/libqb.git
->git show commit:d823a480dc49639fd13ea8ab6e5f586842c64e24
However, the following errors occurred and were not able to make rpm.
-------
PASS: array.test
PASS: map.test
PASS: rb.test
PASS: log.test
PASS: loop.test
PASS: ipc.test
FAIL: resources.test
===================================================
1 of 7 tests failed
See tests/test-suite.log
Please report to quarterback-devel(a)fedorahosted.org
===================================================
make[5]: *** [test-suite.log] Error 1
make[5]: Leaving directory
`/share/ha/buildbot/build/RHEL6.0-x86_64/libqb/libqb-0.7.0.31-d823/tests'
make[4]: *** [check-TESTS] Error 2
make[4]: Leaving directory
`/share/ha/buildbot/build/RHEL6.0-x86_64/libqb/libqb-0.7.0.31-d823/tests'
make[3]: *** [check-am] Error 2
make[3]: Leaving directory
`/share/ha/buildbot/build/RHEL6.0-x86_64/libqb/libqb-0.7.0.31-d823/tests'
make[2]: *** [check-recursive] Error 1
make[2]: Leaving directory
`/share/ha/buildbot/build/RHEL6.0-x86_64/libqb/libqb-0.7.0.31-d823'
make[1]: *** [check] Error 2
make[1]: Leaving directory
`/share/ha/buildbot/build/RHEL6.0-x86_64/libqb/libqb-0.7.0.31-d823'
error: Bad exit status from /var/tmp/rpm-tmp.F0jYH5 (%check)
RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.F0jYH5 (%check)
make: *** [rpm] Error 1
-------
make is completed.
My environment is RHEL6.0.
Thanks in advance for any advice :)
Regards,
Tomo
12 years, 4 months
[PATCH 1/2] IPC: add a new state to the connection state
by Angus Salkeld
This to handle disconnecting in a failure state (before
the connection has been established.
Another aspect to this is we don't want to call
connection_destroyed() if we haven't called
connection_created().
Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
lib/ipc_int.h | 3 ++-
lib/ipc_us.c | 8 +++++---
lib/ipcs.c | 13 +++++++++++--
3 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/lib/ipc_int.h b/lib/ipc_int.h
index c4eb082..72af15f 100644
--- a/lib/ipc_int.h
+++ b/lib/ipc_int.h
@@ -165,7 +165,8 @@ struct qb_ipcs_service {
enum qb_ipcs_connection_state {
QB_IPCS_CONNECTION_INACTIVE,
QB_IPCS_CONNECTION_ACTIVE,
- QB_IPCS_CONNECTION_DOWN,
+ QB_IPCS_CONNECTION_ESTABLISHED,
+ QB_IPCS_CONNECTION_SHUTTING_DOWN,
};
struct qb_ipcs_connection {
diff --git a/lib/ipc_us.c b/lib/ipc_us.c
index 1387b0b..8c989aa 100644
--- a/lib/ipc_us.c
+++ b/lib/ipc_us.c
@@ -526,6 +526,7 @@ handle_new_connection(struct qb_ipcs_service *s,
struct qb_ipcs_connection *c = NULL;
struct qb_ipc_connection_request *req = msg;
int32_t res = auth_result;
+ int32_t res2 = 0;
struct qb_ipc_connection_response response;
c = qb_ipcs_connection_alloc(s);
@@ -605,15 +606,16 @@ send_response:
s->stats.active_connections++;
}
- res = qb_ipc_us_send(&c->setup, &response, response.hdr.size);
- if (res == response.hdr.size) {
- res = 0;
+ res2 = qb_ipc_us_send(&c->setup, &response, response.hdr.size);
+ if (res == 0 && res2 != response.hdr.size) {
+ res = res2;
}
if (res == 0) {
if (s->serv_fns.connection_created) {
s->serv_fns.connection_created(c);
}
+ c->state = QB_IPCS_CONNECTION_ESTABLISHED;
} else {
if (res == -EACCES) {
qb_util_log(LOG_ERR, "Invalid IPC credentials.");
diff --git a/lib/ipcs.c b/lib/ipcs.c
index 569fd45..0710301 100644
--- a/lib/ipcs.c
+++ b/lib/ipcs.c
@@ -496,7 +496,16 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c)
qb_util_log(LOG_DEBUG, "%s() state:%d", __func__, c->state);
if (c->state == QB_IPCS_CONNECTION_ACTIVE) {
- c->state = QB_IPCS_CONNECTION_DOWN;
+ c->state = QB_IPCS_CONNECTION_INACTIVE;
+ c->service->stats.closed_connections++;
+ if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) {
+ qb_ipcc_us_sock_close(c->setup.u.us.sock);
+ c->setup.u.us.sock = -1;
+ qb_ipcs_connection_unref(c);
+ }
+ }
+ if (c->state == QB_IPCS_CONNECTION_ESTABLISHED) {
+ c->state = QB_IPCS_CONNECTION_SHUTTING_DOWN;
c->service->stats.active_connections--;
c->service->stats.closed_connections++;
@@ -506,7 +515,7 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c)
qb_ipcs_connection_unref(c);
}
}
- if (c->state == QB_IPCS_CONNECTION_DOWN) {
+ if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN) {
res = 0;
if (c->service->serv_fns.connection_closed) {
res = c->service->serv_fns.connection_closed(c);
--
1.7.7.4
12 years, 4 months