From 78942f568d83ea621661bfcd2d3f25eee3d316a1 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 13 Nov 2001 22:57:03 +0000 Subject: [PATCH] More work on event queues. *_option returns new value (not previous). --- zoom/zoom-c.c | 254 +++++++++++++++++++++++++++++++++---------------------- zoom/zoom-p.h | 16 +++- zoom/zoomtst1.c | 4 +- zoom/zoomtst7.c | 7 +- 4 files changed, 174 insertions(+), 107 deletions(-) diff --git a/zoom/zoom-c.c b/zoom/zoom-c.c index 21ae004..45181e7 100644 --- a/zoom/zoom-c.c +++ b/zoom/zoom-c.c @@ -1,5 +1,5 @@ /* - * $Id: zoom-c.c,v 1.4 2001-11-11 22:25:25 adam Exp $ + * $Id: zoom-c.c,v 1.5 2001-11-13 22:57:03 adam Exp $ * * ZOOM layer for C, connections, result sets, queries. */ @@ -12,15 +12,59 @@ #include "zoom-p.h" -#define USE_POLL 0 - -#if USE_POLL +#if HAVE_SYS_POLL_H #include #endif -static Z3950_record record_cache_lookup (Z3950_resultset r, - int pos, - const char *elementSetName); +static Z3950_Event Z3950_Event_create (int kind) +{ + Z3950_Event event = xmalloc (sizeof(*event)); + event->kind = kind; + event->next = 0; + event->prev = 0; + return event; +} + +static void Z3950_Event_destroy (Z3950_Event event) +{ + xfree (event); +} + +static void Z3950_connection_put_event (Z3950_connection c, Z3950_Event event) +{ + // put in back of queue + if (c->m_queue_back) + { + c->m_queue_back->prev = event; + assert (c->m_queue_front); + } + else + { + assert (!c->m_queue_front); + c->m_queue_front = event; + } + event->next = c->m_queue_back; + event->prev = 0; + c->m_queue_back = event; +} + +static Z3950_Event Z3950_connection_get_event(Z3950_connection c) +{ + // get from front of queue + Z3950_Event event = c->m_queue_front; + if (!event) + return 0; + assert (c->m_queue_back); + c->m_queue_front = event->prev; + if (c->m_queue_front) + { + assert (c->m_queue_back); + c->m_queue_front->next = 0; + } + else + c->m_queue_back = 0; + return event; +} static void clear_error (Z3950_connection c) { @@ -29,11 +73,58 @@ static void clear_error (Z3950_connection c) c->addinfo = 0; } +Z3950_task Z3950_connection_add_task (Z3950_connection c, int which) +{ + Z3950_task *taskp = &c->tasks; + while (*taskp) + taskp = &(*taskp)->next; + *taskp = xmalloc (sizeof(**taskp)); + (*taskp)->running = 0; + (*taskp)->which = which; + (*taskp)->u.resultset = 0; /* one null pointer there at least */ + (*taskp)->next = 0; + clear_error (c); + return *taskp; +} + +void Z3950_connection_remove_task (Z3950_connection c) +{ + Z3950_task task = c->tasks; + + if (task) + { + c->tasks = task->next; + switch (task->which) + { + case Z3950_TASK_SEARCH: + Z3950_resultset_destroy (task->u.resultset); + break; + case Z3950_TASK_RETRIEVE: + Z3950_resultset_destroy (task->u.resultset); + break; + case Z3950_TASK_CONNECT: + break; + default: + assert (0); + } + xfree (task); + } +} + +void Z3950_connection_remove_tasks (Z3950_connection c) +{ + while (c->tasks) + Z3950_connection_remove_task(c); +} + +static Z3950_record record_cache_lookup (Z3950_resultset r, + int pos, + const char *elementSetName); + Z3950_connection Z3950_connection_create (Z3950_options options) { Z3950_connection c = xmalloc (sizeof(*c)); - c->event_pending = 0; c->cs = 0; c->mask = 0; c->state = STATE_IDLE; @@ -58,6 +149,9 @@ Z3950_connection Z3950_connection_create (Z3950_options options) c->odr_out = odr_createmem (ODR_ENCODE); c->async = 0; + + c->m_queue_front = 0; + c->m_queue_back = 0; return c; } @@ -125,6 +219,7 @@ void Z3950_connection_connect(Z3950_connection c, const char *host, int portnum) { const char *val; + Z3950_task task; val = Z3950_options_get (c->options, "proxy"); if (val && *val) @@ -143,6 +238,8 @@ void Z3950_connection_connect(Z3950_connection c, c->async = Z3950_options_get_bool (c->options, "async", 0); + task = Z3950_connection_add_task (c, Z3950_TASK_CONNECT); + if (!c->async) { while (Z3950_event (1, &c)) @@ -201,49 +298,6 @@ int Z3950_query_sortby(Z3950_query s, const char *criteria) static int do_write(Z3950_connection c); - -Z3950_task Z3950_connection_add_task (Z3950_connection c, int which) -{ - Z3950_task *taskp = &c->tasks; - while (*taskp) - taskp = &(*taskp)->next; - *taskp = xmalloc (sizeof(**taskp)); - (*taskp)->running = 0; - (*taskp)->which = which; - (*taskp)->u.resultset = 0; /* one null pointer there at least */ - (*taskp)->next = 0; - clear_error (c); - return *taskp; -} - -void Z3950_connection_remove_task (Z3950_connection c) -{ - Z3950_task task = c->tasks; - - if (task) - { - c->tasks = task->next; - switch (task->which) - { - case Z3950_TASK_SEARCH: - Z3950_resultset_destroy (task->u.resultset); - break; - case Z3950_TASK_RETRIEVE: - Z3950_resultset_destroy (task->u.resultset); - break; - default: - assert (0); - } - xfree (task); - } -} - -void Z3950_connection_remove_tasks (Z3950_connection c) -{ - while (c->tasks) - Z3950_connection_remove_task(c); -} - void Z3950_connection_destroy(Z3950_connection c) { Z3950_resultset r; @@ -418,7 +472,7 @@ void Z3950_resultset_records (Z3950_resultset r, Z3950_record *recs, } } -static void do_connect (Z3950_connection c) +static int do_connect (Z3950_connection c) { void *add; const char *effective_host; @@ -442,12 +496,12 @@ static void do_connect (Z3950_connection c) c->state = STATE_CONNECTING; c->mask = Z3950_SELECT_READ | Z3950_SELECT_WRITE | Z3950_SELECT_EXCEPT; - return; + return 1; } } - c->event_pending = 1; c->state = STATE_IDLE; c->error = Z3950_ERROR_CONNECT; + return 0; } int z3950_connection_socket(Z3950_connection c) @@ -1083,10 +1137,11 @@ static int Z3950_connection_exec_task (Z3950_connection c) { Z3950_task task = c->tasks; - yaz_log (LOG_DEBUG, "Z3950_connection_exec_task"); + yaz_log (LOG_LOG, "Z3950_connection_exec_task"); if (!task) return 0; - if (c->error != Z3950_ERROR_NONE || !c->cs) + if (c->error != Z3950_ERROR_NONE || + (!c->cs && task->which != Z3950_TASK_CONNECT)) { Z3950_connection_remove_tasks (c); return 0; @@ -1106,6 +1161,9 @@ static int Z3950_connection_exec_task (Z3950_connection c) if (send_present (c)) return 1; break; + case Z3950_TASK_CONNECT: + if (do_connect(c)) + return 1; } Z3950_connection_remove_task (c); return 0; @@ -1142,6 +1200,11 @@ static void handle_apdu (Z3950_connection c, Z_APDU *apdu) c->cookie_in = 0; if (cookie) c->cookie_in = xstrdup(cookie); + if (c->tasks) + { + assert (c->tasks->which == Z3950_TASK_CONNECT); + Z3950_connection_remove_task (c); + } Z3950_connection_exec_task (c); } break; @@ -1226,23 +1289,23 @@ static int do_write(Z3950_connection c) const char *Z3950_connection_option (Z3950_connection c, const char *key, const char *val) { - const char *old_val = Z3950_options_get (c->options, key); if (val) { Z3950_options_set (c->options, key, val); + return val; } - return old_val; + return Z3950_options_get (c->options, key); } const char *Z3950_resultset_option (Z3950_resultset r, const char *key, const char *val) { - const char *old_val = Z3950_options_get (r->options, key); if (val) { Z3950_options_set (r->options, key, val); + return val; } - return old_val; + return Z3950_options_get (r->options, key); } @@ -1307,6 +1370,7 @@ int Z3950_connection_error (Z3950_connection c, const char **cp, int Z3950_connection_do_io(Z3950_connection c, int mask) { + Z3950_Event event; #if 0 int r = cs_look(c->cs); yaz_log (LOG_LOG, "Z3950_connection_do_io c=%p mask=%d cs_look=%d", @@ -1360,13 +1424,15 @@ int Z3950_connection_do_io(Z3950_connection c, int mask) do_close (c); } #endif - c->event_pending = 1; + event = Z3950_Event_create (1); + Z3950_connection_put_event (c, event); return 1; } + int Z3950_event (int no, Z3950_connection *cs) { -#if USE_POLL +#if HAVE_SYS_POLL_H struct pollfd pollfds[1024]; Z3950_connection poll_cs[1024]; #else @@ -1379,14 +1445,20 @@ int Z3950_event (int no, Z3950_connection *cs) for (i = 0; ievent_pending) - { - c->event_pending = 0; + Z3950_Event event; + if (c && (event = Z3950_connection_get_event(c))) + { + Z3950_Event_destroy (event); return i+1; - } + } } - -#if USE_POLL + for (i = 0; ics && c->host_port && c->error == Z3950_ERROR_NONE) - { - do_connect (c); - return i+1; - } - else - { - if (Z3950_connection_exec_task (c)) - return i+1; - } - } - yaz_log (LOG_DEBUG, "no more events"); - return 0; - } -#if USE_POLL + return 0; +#if HAVE_SYS_POLL_H yaz_log (LOG_LOG, "poll start"); r = poll (pollfds, nfds, 15000); yaz_log (LOG_LOG, "poll stop, returned r=%d", r); @@ -1489,9 +1542,11 @@ int Z3950_event (int no, Z3950_connection *cs) } else if (r == 0 && c->mask) { + Z3950_Event event = Z3950_Event_create(0); /* timeout and this connection was waiting */ c->error = Z3950_ERROR_TIMEOUT; - c->event_pending = 1; + do_close (c); + Z3950_connection_put_event(c, event); } } #else @@ -1521,23 +1576,24 @@ int Z3950_event (int no, Z3950_connection *cs) } if (r == 0 && c->mask) { + Z3950_Event event = Z3950_Event_create(0); /* timeout and this connection was waiting */ c->error = Z3950_ERROR_TIMEOUT; - c->event_pending = 1; + do_close (c); + yaz_log (LOG_LOG, "timeout"); + Z3950_connection_put_event(c, event); } } #endif - for (i = 0; ievent_pending) - { - c->event_pending = 0; + Z3950_Event event; + if (c && (event = Z3950_connection_get_event(c))) + { + Z3950_Event_destroy (event); return i+1; - } + } } return 0; } diff --git a/zoom/zoom-p.h b/zoom/zoom-p.h index 1c9a1ff..5958aff 100644 --- a/zoom/zoom-p.h +++ b/zoom/zoom-p.h @@ -1,12 +1,14 @@ /* * Private C header for ZOOM C. - * $Id: zoom-p.h,v 1.3 2001-11-06 17:05:19 adam Exp $ + * $Id: zoom-p.h,v 1.4 2001-11-13 22:57:03 adam Exp $ */ #include #include #include #include +typedef struct Z3950_Event_p *Z3950_Event; + struct Z3950_query_p { Z_Query *query; Z_SortKeySpecList *sort_spec; @@ -39,10 +41,11 @@ struct Z3950_connection_p { char *cookie_out; char *cookie_in; int async; - int event_pending; Z3950_task tasks; Z3950_options options; Z3950_resultset resultsets; + Z3950_Event m_queue_front; + Z3950_Event m_queue_back; }; @@ -99,11 +102,18 @@ struct Z3950_task_p { Z3950_resultset resultset; #define Z3950_TASK_RETRIEVE 2 /** also resultset here */ - +#define Z3950_TASK_CONNECT 3 } u; Z3950_task next; }; +struct Z3950_Event_p { + int kind; + Z3950_Event next; + Z3950_Event prev; +}; + + #ifndef YAZ_DATE COMSTACK cs_create_host(const char *type_and_host, int blocking, void **vp); Odr_oid *yaz_str_to_z3950oid (ODR o, int oid_class, const char *str); diff --git a/zoom/zoomtst1.c b/zoom/zoomtst1.c index 08c6bb8..f21d30b 100644 --- a/zoom/zoomtst1.c +++ b/zoom/zoomtst1.c @@ -1,12 +1,12 @@ /* - * $Id: zoomtst1.c,v 1.1 2001-10-23 21:00:20 adam Exp $ + * $Id: zoomtst1.c,v 1.2 2001-11-13 22:57:03 adam Exp $ * * Synchronous single-target client doing search (but no retrieval) */ #include #include - +#include #include int main(int argc, char **argv) diff --git a/zoom/zoomtst7.c b/zoom/zoomtst7.c index 6c3aa6b..39c4bbb 100644 --- a/zoom/zoomtst7.c +++ b/zoom/zoomtst7.c @@ -1,5 +1,5 @@ /* - * $Id: zoomtst7.c,v 1.4 2001-11-11 22:25:25 adam Exp $ + * $Id: zoomtst7.c,v 1.5 2001-11-13 22:57:03 adam Exp $ * * API test.. */ @@ -75,8 +75,11 @@ int main(int argc, char **argv) r[j] = Z3950_connection_search (z, s); /* non-piggy */ Z3950_resultset_records (r[j], recs, 0, 2); /* first two */ + Z3950_record_destroy (recs[0]); + Z3950_record_destroy (recs[1]); Z3950_resultset_records (r[j], recs, 1, 2); /* third */ + Z3950_resultset_records (r[j], recs, 0, 0); /* ignored */ if (Z3950_resultset_size (r[j]) > 2) @@ -149,5 +152,3 @@ int main(int argc, char **argv) exit (0); } - - -- 1.7.10.4