From 56a55ffd1562165febc1a2a66d0c2a95e966d540 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 2 Oct 2007 12:11:14 +0000 Subject: [PATCH] Use queue for raw show; to solve Bug #1644. The client system now makes a queue of requests to be carried out (struct show_raw). Howevever, HTTP connection closing could be handled more elegantly (to say the least). --- src/client.c | 80 ++++++++++++++++++++++++++++++++-------------------- src/client.h | 7 +++-- src/http.c | 14 +++++++-- src/http.h | 6 ++-- src/http_command.c | 18 +++++------- src/logic.c | 5 ++-- 6 files changed, 79 insertions(+), 51 deletions(-) diff --git a/src/client.c b/src/client.c index dffb359..ca8b067 100644 --- a/src/client.c +++ b/src/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.27 2007-10-02 10:32:03 adam Exp $ +/* $Id: client.c,v 1.28 2007-10-02 12:11:14 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -89,6 +89,7 @@ struct show_raw { void (*error_handler)(void *data, const char *addinfo); void (*record_handler)(void *data, const char *buf, size_t sz); void *data; + struct show_raw *next; }; static const char *client_states[] = { @@ -236,32 +237,35 @@ int client_show_raw_begin(struct client *cl, int position, void *data, void (*error_handler)(void *data, const char *addinfo), void (*record_handler)(void *data, const char *buf, - size_t sz)) + size_t sz), + void **data2) { - if (cl->show_raw) - { /* raw show already in progress */ - return -1; - } + struct show_raw *rr, **rrp; if (!cl->connection) { /* the client has no connection */ - return -2; + return -1; } - cl->show_raw = xmalloc(sizeof(*cl->show_raw)); - cl->show_raw->position = position; - cl->show_raw->active = 0; - cl->show_raw->data = data; - cl->show_raw->error_handler = error_handler; - cl->show_raw->record_handler = record_handler; + rr = xmalloc(sizeof(*rr)); + *data2 = rr; + rr->position = position; + rr->active = 0; + rr->data = data; + rr->error_handler = error_handler; + rr->record_handler = record_handler; if (syntax) - cl->show_raw->syntax = xstrdup(syntax); + rr->syntax = xstrdup(syntax); else - cl->show_raw->syntax = 0; + rr->syntax = 0; if (esn) - cl->show_raw->esn = xstrdup(esn); + rr->esn = xstrdup(esn); else - cl->show_raw->esn = 0; + rr->esn = 0; + rr->next = 0; + + for (rrp = &cl->show_raw; *rrp; rrp = &(*rrp)->next) + ; + *rrp = rr; - if (cl->state == Client_Failed) { client_show_raw_error(cl, "client failed"); @@ -277,27 +281,42 @@ int client_show_raw_begin(struct client *cl, int position, return 0; } -void client_show_raw_reset(struct client *cl) +void client_show_raw_remove(struct client *cl, void *data) +{ + struct show_raw *rr = data; + struct show_raw **rrp = &cl->show_raw; + while (*rrp != rr) + rrp = &(*rrp)->next; + if (*rrp) + { + *rrp = rr->next; + xfree(rr); + } +} + +void client_show_raw_dequeue(struct client *cl) { - xfree(cl->show_raw); - cl->show_raw = 0; + struct show_raw *rr = cl->show_raw; + + cl->show_raw = rr->next; + xfree(rr); } static void client_show_raw_error(struct client *cl, const char *addinfo) { - if (cl->show_raw) + while (cl->show_raw) { cl->show_raw->error_handler(cl->show_raw->data, addinfo); - client_show_raw_reset(cl); + client_show_raw_dequeue(cl); } } static void client_show_raw_cancel(struct client *cl) { - if (cl->show_raw) + while (cl->show_raw) { cl->show_raw->error_handler(cl->show_raw->data, "cancel"); - client_show_raw_reset(cl); + client_show_raw_dequeue(cl); } } @@ -555,12 +574,13 @@ static void ingest_raw_records(struct client *cl, Z_Records *r) xmlDocDumpMemory(doc, &buf_out, &len_out); xmlFreeDoc(doc); - cl->show_raw->record_handler(cl->show_raw->data, - (const char *) buf_out, len_out); - + if (cl->show_raw) + { + cl->show_raw->record_handler(cl->show_raw->data, + (const char *) buf_out, len_out); + client_show_raw_dequeue(cl); + } xmlFree(buf_out); - xfree(cl->show_raw); - cl->show_raw = 0; } static void ingest_records(struct client *cl, Z_Records *r) diff --git a/src/client.h b/src/client.h index ba40fc1..7af4630 100644 --- a/src/client.h +++ b/src/client.h @@ -1,4 +1,4 @@ -/* $Id: client.h,v 1.4 2007-09-20 08:13:27 adam Exp $ +/* $Id: client.h,v 1.5 2007-10-02 12:11:14 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -49,8 +49,9 @@ int client_show_raw_begin(struct client *cl, int position, void *data, void (*error_handler)(void *data, const char *addinfo), void (*record_handler)(void *data, const char *buf, - size_t sz)); -void client_show_raw_reset(struct client *cl); + size_t sz), + void **data2); +void client_show_raw_remove(struct client *cl, void *rr); const char *client_get_state_str(struct client *cl); enum client_state client_get_state(struct client *cl); diff --git a/src/http.c b/src/http.c index dfc4f38..9a142d7 100644 --- a/src/http.c +++ b/src/http.c @@ -1,4 +1,4 @@ -/* $Id: http.c,v 1.40 2007-09-26 09:09:15 adam Exp $ +/* $Id: http.c,v 1.41 2007-10-02 12:11:14 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -68,7 +68,8 @@ static struct http_channel *http_channel_freelist = 0; struct http_channel_observer_s { void *data; - void (*destroy)(void *data, struct http_channel *chan); + void *data2; + http_channel_destroy_t destroy; struct http_channel_observer_s *next; struct http_channel *chan; }; @@ -1227,7 +1228,7 @@ static void http_fire_observers(struct http_channel *c) http_channel_observer_t p = c->observers; while (p) { - p->destroy(p->data, c); + p->destroy(p->data, c, p->data2); p = p->next; } } @@ -1248,6 +1249,7 @@ http_channel_observer_t http_add_observer(struct http_channel *c, void *data, http_channel_observer_t obs = xmalloc(sizeof(*obs)); obs->chan = c; obs->data = data; + obs->data2 = 0; obs->destroy= des; obs->next = c->observers; c->observers = obs; @@ -1271,6 +1273,12 @@ struct http_channel *http_channel_observer_chan(http_channel_observer_t obs) return obs->chan; } +void http_observer_set_data2(http_channel_observer_t obs, void *data2) +{ + obs->data2 = data2; +} + + /* * Local variables: * c-basic-offset: 4 diff --git a/src/http.h b/src/http.h index ba8f163..ffb1ca9 100644 --- a/src/http.h +++ b/src/http.h @@ -1,4 +1,4 @@ -/* $Id: http.h,v 1.11 2007-09-26 08:53:53 adam Exp $ +/* $Id: http.h,v 1.12 2007-10-02 12:11:14 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -114,10 +114,12 @@ struct http_response *http_create_response(struct http_channel *c); void http_send_response(struct http_channel *c); void urlencode(const char *i, char *o); -typedef void (*http_channel_destroy_t)(void *data, struct http_channel *c); +typedef void (*http_channel_destroy_t)(void *data, struct http_channel *c, + void *data2); http_channel_observer_t http_add_observer(struct http_channel *c, void *data, http_channel_destroy_t); +void http_observer_set_data2(http_channel_observer_t obs, void *data2); void http_remove_observer(http_channel_observer_t obs); struct http_channel *http_channel_observer_chan(http_channel_observer_t obs); diff --git a/src/http_command.c b/src/http_command.c index 447eb06..7be4e07 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -1,4 +1,4 @@ -/* $Id: http_command.c,v 1.63 2007-10-02 10:11:56 adam Exp $ +/* $Id: http_command.c,v 1.64 2007-10-02 12:11:14 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -20,7 +20,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA */ /* - * $Id: http_command.c,v 1.63 2007-10-02 10:11:56 adam Exp $ + * $Id: http_command.c,v 1.64 2007-10-02 12:11:14 adam Exp $ */ #include @@ -513,10 +513,10 @@ static void show_raw_record_ok(void *data, const char *buf, size_t sz) http_send_response(c); } -void show_raw_reset(void *data, struct http_channel *c) +void show_raw_reset(void *data, struct http_channel *c, void *data2) { struct client *client = data; - client_show_raw_reset(client); + client_show_raw_remove(client, data2); } static void cmd_record_ready(void *data); @@ -566,22 +566,18 @@ static void cmd_record(struct http_channel *c) } else { + void *data2; http_channel_observer_t obs = http_add_observer(c, r->client, show_raw_reset); int ret = client_show_raw_begin(r->client, r->position, syntax, esn, obs /* data */, show_raw_record_error, - show_raw_record_ok); + show_raw_record_ok, + &data2); if (ret == -1) { http_remove_observer(obs); - error(rs, PAZPAR2_RECORD_FAIL, "show already active"); - return; - } - else if (ret == -2) - { - http_remove_observer(obs); error(rs, PAZPAR2_NO_SESSION, 0); return; } diff --git a/src/logic.c b/src/logic.c index 2316945..625adc0 100644 --- a/src/logic.c +++ b/src/logic.c @@ -1,4 +1,4 @@ -/* $Id: logic.c,v 1.68 2007-10-02 10:08:39 adam Exp $ +/* $Id: logic.c,v 1.69 2007-10-02 12:11:14 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -525,7 +525,8 @@ static int prepare_session_database(struct session *se, } // called if watch should be removed because http_channel is to be destroyed -static void session_watch_cancel(void *data, struct http_channel *c) +static void session_watch_cancel(void *data, struct http_channel *c, + void *data2) { struct session_watchentry *ent = data; -- 1.7.10.4