From: Dennis Schafroth Date: Thu, 29 Apr 2010 08:42:32 +0000 (+0200) Subject: Merge branch 'master' into channel_list_mutex X-Git-Tag: v1.4.0~3^2~2 X-Git-Url: http://git.indexdata.com/?a=commitdiff_plain;h=2ebf0b250fd141b7a3e186e7e99bfc76e29e39d7;hp=ce617dd90a2dc6632e7475ab73a887e0fb472c5c;p=pazpar2-moved-to-github.git Merge branch 'master' into channel_list_mutex --- diff --git a/etc/tmarcxml.xsl b/etc/tmarcxml.xsl deleted file mode 100644 index 42ae103..0000000 --- a/etc/tmarcxml.xsl +++ /dev/null @@ -1,838 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - electronic resource - - - electronic resource - - - article - - - book - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - , - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - , - - - - - - - - - diff --git a/perf/bash/.gitignore b/perf/bash/.gitignore index 0da406c..c5413bf 100644 --- a/perf/bash/.gitignore +++ b/perf/bash/.gitignore @@ -1,2 +1,4 @@ *.log *.xml +*.time +run* diff --git a/perf/bash/par.sh b/perf/bash/par.sh index b01a265..0374b46 100755 --- a/perf/bash/par.sh +++ b/perf/bash/par.sh @@ -1,7 +1,7 @@ #!/bin/bash DELAY=0.001 WAIT=5 -NUMBER=40 +NUMBER=10 ROUNDS=5 if test -n "$1"; then . $1 diff --git a/src/eventl.c b/src/eventl.c index f9f0dc2..6b8f52f 100644 --- a/src/eventl.c +++ b/src/eventl.c @@ -1,21 +1,21 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2010 Index Data + Copyright (C) 2006-2010 Index Data -Pazpar2 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. + Pazpar2 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. -Pazpar2 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. + Pazpar2 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 this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + */ /* * Based on ParaZ - a simple tool for harvesting performance data for @@ -53,6 +53,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include #include +#include +#include #include "eventl.h" #include "sel_thread.h" @@ -62,31 +64,35 @@ struct iochan_man_s { int sel_fd; int no_threads; int log_level; + YAZ_MUTEX iochan_mutex; +}; + +struct iochan_man_iter { + iochan_man_t man; + IOCHAN current; + int first; }; -iochan_man_t iochan_man_create(int no_threads) -{ +iochan_man_t iochan_man_create(int no_threads) { iochan_man_t man = xmalloc(sizeof(*man)); man->channel_list = 0; man->sel_thread = 0; /* can't create sel_thread yet because we may fork */ man->sel_fd = -1; man->no_threads = no_threads; man->log_level = yaz_log_module_level("iochan"); - + man->iochan_mutex = 0; + yaz_mutex_create(&man->iochan_mutex); return man; } -void iochan_man_destroy(iochan_man_t *mp) -{ - if (*mp) - { +void iochan_man_destroy(iochan_man_t *mp) { + if (*mp) { IOCHAN c; if ((*mp)->sel_thread) sel_thread_destroy((*mp)->sel_thread); - + c = (*mp)->channel_list; - while (c) - { + while (c) { IOCHAN c_next = c->next; xfree(c->name); xfree(c); @@ -97,20 +103,21 @@ void iochan_man_destroy(iochan_man_t *mp) } } -void iochan_add(iochan_man_t man, IOCHAN chan) -{ +void iochan_add(iochan_man_t man, IOCHAN chan) { chan->man = man; + yaz_mutex_enter(man->iochan_mutex); + yaz_log(man->log_level, "iochan_add : chan=%p channel list=%p", chan, + man->channel_list); chan->next = man->channel_list; man->channel_list = chan; + yaz_mutex_leave(man->iochan_mutex); } -IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, - const char *name) -{ +IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, const char *name) { IOCHAN new_iochan; - if (!(new_iochan = (IOCHAN)xmalloc(sizeof(*new_iochan)))) - return 0; + if (!(new_iochan = (IOCHAN) xmalloc(sizeof(*new_iochan)))) + return 0; new_iochan->destroyed = 0; new_iochan->fd = fd; new_iochan->flags = flags; @@ -123,13 +130,12 @@ IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags, return new_iochan; } -static void work_handler(void *work_data) -{ +static void work_handler(void *work_data) { IOCHAN p = work_data; yaz_log(p->man->log_level, "eventl: work begin chan=%p name=%s event=%d", p, p->name ? p->name : "", p->this_event); - + if (!p->destroyed && (p->this_event & EVENT_TIMEOUT)) (*p->fun)(p, EVENT_TIMEOUT); if (!p->destroyed && (p->this_event & EVENT_INPUT)) @@ -139,62 +145,101 @@ static void work_handler(void *work_data) if (!p->destroyed && (p->this_event & EVENT_EXCEPT)) (*p->fun)(p, EVENT_EXCEPT); - yaz_log(p->man->log_level, "eventl: work end chan=%p name=%s event=%d", - p, p->name ? p->name : "", p->this_event); + yaz_log(p->man->log_level, "eventl: work end chan=%p name=%s event=%d", p, + p->name ? p->name : "", p->this_event); } -static void run_fun(iochan_man_t man, IOCHAN p) -{ - if (p->this_event) - { - if (man->sel_thread) - { - yaz_log(man->log_level, "eventl: work add chan=%p name=%s event=%d", - p, p->name ? p->name : "", p->this_event); +static void run_fun(iochan_man_t man, IOCHAN p) { + if (p->this_event) { + if (man->sel_thread) { + yaz_log(man->log_level, + "eventl: work add chan=%p name=%s event=%d", p, + p->name ? p->name : "", p->this_event); p->thread_users++; sel_thread_add(man->sel_thread, p); - } - else + } else work_handler(p); } } -static int event_loop(iochan_man_t man, IOCHAN *iochans) -{ +static IOCHAN iochan_man_get_first(struct iochan_man_iter *iter, + iochan_man_t man) { + iter->man = man; + iter->first = 1; + yaz_mutex_enter(man->iochan_mutex); + iter->current = man->channel_list; + yaz_log(man->log_level, "iochan_man_get_first : chan=%p ", iter->current); + if (!iter->current) + yaz_mutex_leave(man->iochan_mutex); + return iter->current; +} + +static IOCHAN iochan_man_get_next(struct iochan_man_iter *iter) { + IOCHAN current = NULL, next = NULL; + current = iter->current; + assert(current); + if (current) { + next = current->next; + iter->current = iter->current->next; + if (iter->first) { + yaz_log(iter->man->log_level, + "iochan_man_get_next : chan=%p next=%p", current, next); + iter->first = 0; + yaz_mutex_leave(iter->man->iochan_mutex); + } + } + return iter->current; +} + +static int event_loop(iochan_man_t man, IOCHAN *iochans) { do /* loop as long as there are active associations to process */ { - IOCHAN p, *nextp; - fd_set in, out, except; - int res, max; - static struct timeval to; - struct timeval *timeout; - - FD_ZERO(&in); - FD_ZERO(&out); - FD_ZERO(&except); - timeout = &to; /* hang on select */ - to.tv_sec = 300; - to.tv_usec = 0; - max = 0; - for (p = *iochans; p; p = p->next) - { + IOCHAN p, *nextp; + IOCHAN start; + fd_set in, out, except; + int res, max; + static struct timeval to; + struct timeval *timeout; + static struct iochan_man_iter iter; + +// struct yaz_poll_fd *fds; + int no_fds = 0; + FD_ZERO(&in); + FD_ZERO(&out); + FD_ZERO(&except); + timeout = &to; /* hang on select */ + to.tv_sec = 300; + to.tv_usec = 0; + + // INV: Start must no change through the loop + + start = iochan_man_get_first(&iter, man); + IOCHAN inv_start = start; + for (p = start; p; p = iochan_man_get_next(&iter)) { + no_fds++; + } +// fds = (struct yaz_poll_fd *) xmalloc(no_fds * sizeof(*fds)); + + max = 0; + for (p = start; p; p = p->next) { if (p->thread_users > 0) continue; if (p->max_idle && p->max_idle < to.tv_sec) to.tv_sec = p->max_idle; if (p->fd < 0) continue; - if (p->flags & EVENT_INPUT) - FD_SET(p->fd, &in); - if (p->flags & EVENT_OUTPUT) - FD_SET(p->fd, &out); - if (p->flags & EVENT_EXCEPT) - FD_SET(p->fd, &except); - if (p->fd > max) - max = p->fd; - } - if (man->sel_fd != -1) - { + if (p->flags & EVENT_INPUT) + FD_SET(p->fd, &in); + if (p->flags & EVENT_OUTPUT) + FD_SET(p->fd, &out); + if (p->flags & EVENT_EXCEPT) + FD_SET(p->fd, &except); + if (p->fd > max) + max = p->fd; + } + yaz_log(man->log_level, "max=%d nofds=%d", max, man->sel_fd); + + if (man->sel_fd != -1) { if (man->sel_fd > max) max = man->sel_fd; FD_SET(man->sel_fd, &in); @@ -202,111 +247,100 @@ static int event_loop(iochan_man_t man, IOCHAN *iochans) yaz_log(man->log_level, "select begin nofds=%d", max); res = select(max + 1, &in, &out, &except, timeout); yaz_log(man->log_level, "select returned res=%d", res); - if (res < 0) - { - if (errno == EINTR) - continue; - else - { - yaz_log(YLOG_ERRNO|YLOG_WARN, "select"); + if (res < 0) { + if (errno == EINTR) + continue; + else { + yaz_log(YLOG_ERRNO | YLOG_WARN, "select"); return 0; } - } - if (man->sel_fd != -1) - { - if (FD_ISSET(man->sel_fd, &in)) - { + } + if (man->sel_fd != -1) { + if (FD_ISSET(man->sel_fd, &in)) { IOCHAN chan; yaz_log(man->log_level, "eventl: sel input on sel_fd=%d", man->sel_fd); - while ((chan = sel_thread_result(man->sel_thread))) - { - yaz_log(man->log_level, "eventl: got thread result chan=%p name=%s", - chan, chan->name ? chan->name : ""); + while ((chan = sel_thread_result(man->sel_thread))) { + yaz_log(man->log_level, + "eventl: got thread result chan=%p name=%s", chan, + chan->name ? chan->name : ""); chan->thread_users--; } } } - if (man->log_level) - { + if (man->log_level) { int no = 0; - for (p = *iochans; p; p = p->next) + for (p = iochan_man_get_first(&iter, man); p; p + = iochan_man_get_next(&iter)) { no++; + } yaz_log(man->log_level, "%d channels", no); } - for (p = *iochans; p; p = p->next) - { + for (p = start; p; p = p->next) { time_t now = time(0); - - if (p->destroyed) - { - yaz_log(man->log_level, "eventl: skip destroyed chan=%p name=%s", p, p->name ? p->name : ""); + + if (p->destroyed) { + yaz_log(man->log_level, + "eventl: skip destroyed chan=%p name=%s", p, + p->name ? p->name : ""); continue; } - if (p->thread_users > 0) - { - yaz_log(man->log_level, "eventl: skip chan=%p name=%s users=%d", p, p->name ? p->name : "", p->thread_users); + if (p->thread_users > 0) { + yaz_log(man->log_level, + "eventl: skip chan=%p name=%s users=%d", p, + p->name ? p->name : "", p->thread_users); continue; } p->this_event = 0; - if (p->max_idle && now - p->last_event > p->max_idle) - { + if (p->max_idle && now - p->last_event > p->max_idle) { p->last_event = now; p->this_event |= EVENT_TIMEOUT; } - if (p->fd >= 0) - { - if (FD_ISSET(p->fd, &in)) - { + if (p->fd >= 0) { + if (FD_ISSET(p->fd, &in)) { p->last_event = now; p->this_event |= EVENT_INPUT; } - if (FD_ISSET(p->fd, &out)) - { + if (FD_ISSET(p->fd, &out)) { p->last_event = now; p->this_event |= EVENT_OUTPUT; } - if (FD_ISSET(p->fd, &except)) - { + if (FD_ISSET(p->fd, &except)) { p->last_event = now; p->this_event |= EVENT_EXCEPT; } } run_fun(man, p); - } - for (nextp = iochans; *nextp; ) - { + } + assert(inv_start == start); + yaz_mutex_enter(man->iochan_mutex); + for (nextp = iochans; *nextp;) { IOCHAN p = *nextp; - if (p->destroyed && p->thread_users == 0) - { + if (p->destroyed && p->thread_users == 0) { *nextp = p->next; xfree(p->name); xfree(p); - } - else + } else nextp = &p->next; } - } - while (*iochans); + yaz_mutex_leave(man->iochan_mutex); + } while (*iochans); return 0; } -void iochan_man_events(iochan_man_t man) -{ - if (man->no_threads > 0 && !man->sel_thread) - { - man->sel_thread = sel_thread_create( - work_handler, 0 /*work_destroy */, &man->sel_fd, man->no_threads); +void iochan_man_events(iochan_man_t man) { + if (man->no_threads > 0 && !man->sel_thread) { + man->sel_thread = sel_thread_create(work_handler, 0 /*work_destroy */, + &man->sel_fd, man->no_threads); yaz_log(man->log_level, "iochan_man_events. Using %d threads", man->no_threads); } event_loop(man, &man->channel_list); } -void pazpar2_sleep(double d) -{ +void pazpar2_sleep(double d) { #ifdef WIN32 Sleep( (DWORD) (d * 1000)); #else diff --git a/src/http_command.c b/src/http_command.c index 9b1825d..b37eca9 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -61,6 +61,7 @@ struct http_session { struct http_sessions { struct http_session *session_list; YAZ_MUTEX mutex; + int log_level; }; http_sessions_t http_sessions_create(void) @@ -69,6 +70,7 @@ http_sessions_t http_sessions_create(void) hs->session_list = 0; hs->mutex = 0; pazpar2_mutex_create(&hs->mutex, "http_sessions"); + hs->log_level = yaz_log_module_level("HTTP"); return hs; } @@ -121,7 +123,7 @@ struct http_session *http_session_create(struct conf_service *service, r->timeout_iochan = iochan_create(-1, session_timeout, 0, "http_session_timeout"); iochan_setdata(r->timeout_iochan, r); - yaz_log(YLOG_LOG, "timeout=%d", service->session_timeout); + yaz_log(http_sessions->log_level, "%p Session %u created. timeout chan=%p timeout=%d", r, sesid, r->timeout_iochan, service->session_timeout); iochan_settimeout(r->timeout_iochan, service->session_timeout); iochan_add(service->server->iochan_man, r->timeout_iochan); @@ -130,22 +132,16 @@ struct http_session *http_session_create(struct conf_service *service, void http_session_destroy(struct http_session *s) { - int must_destroy = 1; + int must_destroy = 0; http_sessions_t http_sessions = s->http_sessions; - yaz_log(YLOG_LOG, "http_session_destroy %u", s->session_id); + yaz_log(http_sessions->log_level, "%p Session %u destroyed", s, s->session_id); yaz_mutex_enter(http_sessions->mutex); - - /* only if http_session destroy was already called, we will allow it - to be destroyed */ - if (s->destroy_counter != s->activity_counter) - must_destroy = 0; - - s->destroy_counter = s->activity_counter = 0; - if (must_destroy) - { + /* only if http_session has no active http sessions on it can be destroyed */ + if (s->destroy_counter == s->activity_counter) { struct http_session **p = 0; + must_destroy = 1; for (p = &http_sessions->session_list; *p; p = &(*p)->next) if (*p == s) { @@ -156,13 +152,14 @@ void http_session_destroy(struct http_session *s) yaz_mutex_leave(http_sessions->mutex); if (must_destroy) { /* destroying for real */ - yaz_log(YLOG_LOG, "Destroying session %u", s->session_id); + yaz_log(http_sessions->log_level, "%p Session %u destroyed", s, s->session_id); iochan_destroy(s->timeout_iochan); destroy_session(s->psession); nmem_destroy(s->nmem); } else { - yaz_log(YLOG_LOG, "Active clients on session %u. Waiting for new timeout.", s->session_id); + yaz_log(http_sessions->log_level, "%p Session %u destroyed delayed. Active clients (%d-%d). Waiting for new timeout.", + s, s->session_id, s->activity_counter, s->destroy_counter); } } @@ -282,6 +279,15 @@ static struct http_session *locate_session(struct http_channel *c) return p; } +// Call after use of locate_session, in order to increment the destroy_counter +static void release_session(struct http_channel *c, struct http_session *session) { + http_sessions_t http_sessions = c->http_sessions; + yaz_mutex_enter(http_sessions->mutex); + if (session) + session->destroy_counter++; + yaz_mutex_leave(http_sessions->mutex); +} + // Decode settings parameters and apply to session // Syntax: setting[target]=value static int process_settings(struct session *se, struct http_request *rq, @@ -362,11 +368,11 @@ static void cmd_init(struct http_channel *c) sesid = make_sessionid(); s = http_session_create(service, c->http_sessions, sesid); - yaz_log(YLOG_DEBUG, "HTTP Session init"); + yaz_log(c->http_sessions->log_level, "%p Session init %u ", s, sesid); if (!clear || *clear == '0') session_init_databases(s->psession); else - yaz_log(YLOG_LOG, "No databases preloaded"); + yaz_log(YLOG_LOG, "HTTP Session %u init: No databases preloaded", sesid); if (process_settings(s->psession, c->request, c->response) < 0) return; @@ -420,10 +426,13 @@ static void cmd_settings(struct http_channel *c) xmlFreeDoc(doc); } - if (process_settings(s->psession, rq, rs) < 0) + if (process_settings(s->psession, rq, rs) < 0) { + release_session(c,s); return; + } rs->payload = HTTP_COMMAND_RESPONSE_PREFIX "OK"; http_send_response(c); + release_session(c,s); } // Compares two hitsbytarget nodes by hitcount @@ -546,6 +555,7 @@ static void cmd_termlist(struct http_channel *c) wrbuf_puts(c->wrbuf, "\n"); rs->payload = nmem_strdup(rq->channel->nmem, wrbuf_cstr(c->wrbuf)); http_send_response(c); + release_session(c,s); } @@ -599,6 +609,7 @@ static void cmd_bytarget(struct http_channel *c) wrbuf_puts(c->wrbuf, ""); rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf)); http_send_response(c); + release_session(c,s); } static void write_metadata(WRBUF w, struct conf_service *service, @@ -741,6 +752,7 @@ static void cmd_record(struct http_channel *c) { error(rs, PAZPAR2_RECORD_MISSING, idstr); } + release_session(c, s); return; } if (offsetstr) @@ -808,6 +820,7 @@ static void cmd_record(struct http_channel *c) http_send_response(c); } show_single_stop(s->psession, rec); + release_session(c, s); } static void cmd_record_ready(void *data) @@ -849,6 +862,7 @@ static void show_records(struct http_channel *c, int active) if (!(sp = reclist_parse_sortparms(c->nmem, sort, s->psession->service))) { error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "sort"); + release_session(c, s); return; } @@ -890,6 +904,7 @@ static void show_records(struct http_channel *c, int active) wrbuf_puts(c->wrbuf, "\n"); rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf)); http_send_response(c); + release_session(c, s); } static void show_records_ready(void *data) @@ -919,13 +934,14 @@ static void cmd_show(struct http_channel *c) if (session_set_watch(s->psession, SESSION_WATCH_SHOW, show_records_ready, c, c) != 0) { - yaz_log(YLOG_DEBUG, "Blocking on cmd_show"); + yaz_log(c->http_sessions->log_level, "%p Session %u: Blocking on cmd_show", s, s->session_id); } + release_session(c,s); return; } } - show_records(c, status); + release_session(c,s); } static void cmd_ping(struct http_channel *c) @@ -936,6 +952,7 @@ static void cmd_ping(struct http_channel *c) return; rs->payload = HTTP_COMMAND_RESPONSE_PREFIX "OK"; http_send_response(c); + release_session(c, s); } static int utf_8_valid(const char *str) @@ -980,21 +997,25 @@ static void cmd_search(struct http_channel *c) if (!query) { error(rs, PAZPAR2_MISSING_PARAMETER, "query"); + release_session(c,s); return; } if (!utf_8_valid(query)) { error(rs, PAZPAR2_MALFORMED_PARAMETER_ENCODING, "query"); + release_session(c,s); return; } code = search(s->psession, query, startrecs, maxrecs, filter, &addinfo); if (code) { error(rs, code, addinfo); + release_session(c,s); return; } rs->payload = HTTP_COMMAND_RESPONSE_PREFIX "OK"; http_send_response(c); + release_session(c,s); } @@ -1033,6 +1054,7 @@ static void cmd_stat(struct http_channel *c) wrbuf_puts(c->wrbuf, ""); rs->payload = nmem_strdup(c->nmem, wrbuf_cstr(c->wrbuf)); http_send_response(c); + release_session(c,s); } static void cmd_info(struct http_channel *c) diff --git a/src/sel_thread.c b/src/sel_thread.c index 10b6d16..0677761 100644 --- a/src/sel_thread.c +++ b/src/sel_thread.c @@ -69,6 +69,8 @@ struct sel_thread { void (*work_destroy)(void *work_data); }; +static int input_queue_length = 0; + static void *sel_thread_handler(void *vp) { sel_thread_t p = (sel_thread_t) vp; @@ -87,6 +89,8 @@ static void *sel_thread_handler(void *vp) assert(p->input_queue); work_this = queue_remove_last(&p->input_queue); + input_queue_length--; + yaz_log(YLOG_DEBUG, "input queue length after pop: %d", input_queue_length); assert(work_this); pthread_mutex_unlock(&p->mutex); @@ -185,7 +189,8 @@ void sel_thread_add(sel_thread_t p, void *data) work_p->data = data; work_p->next = p->input_queue; p->input_queue = work_p; - + input_queue_length++; + yaz_log(YLOG_DEBUG, "sel_thread_add: Input queue length after push: %d", input_queue_length); pthread_cond_signal(&p->input_data); pthread_mutex_unlock(&p->mutex); } diff --git a/src/session.c b/src/session.c index 14b9a2c..b17b29b 100644 --- a/src/session.c +++ b/src/session.c @@ -674,21 +674,22 @@ void session_apply_setting(struct session *se, char *dbname, char *setting, } } -void destroy_session(struct session *s) +void destroy_session(struct session *se) { struct session_database *sdb; - session_remove_clients(s); + yaz_log(YLOG_DEBUG, "%p Pazpar2 session destroy", se); + session_remove_clients(se); - for (sdb = s->databases; sdb; sdb = sdb->next) + for (sdb = se->databases; sdb; sdb = sdb->next) session_database_destroy(sdb); - normalize_cache_destroy(s->normalize_cache); - relevance_destroy(&s->relevance); - reclist_destroy(s->reclist); - nmem_destroy(s->nmem); - service_destroy(s->service); - yaz_mutex_destroy(&s->session_mutex); - wrbuf_destroy(s->wrbuf); + normalize_cache_destroy(se->normalize_cache); + relevance_destroy(&se->relevance); + reclist_destroy(se->reclist); + nmem_destroy(se->nmem); + service_destroy(se->service); + yaz_mutex_destroy(&se->session_mutex); + wrbuf_destroy(se->wrbuf); } struct session *new_session(NMEM nmem, struct conf_service *service, @@ -697,7 +698,7 @@ struct session *new_session(NMEM nmem, struct conf_service *service, int i; struct session *session = nmem_malloc(nmem, sizeof(*session)); - yaz_log(YLOG_DEBUG, "New Pazpar2 session"); + yaz_log(YLOG_DEBUG, "%p New Pazpar2 session", session); session->service = service; session->relevance = 0; @@ -758,19 +759,19 @@ struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem) return res; } -struct termlist_score **termlist(struct session *s, const char *name, int *num) +struct termlist_score **termlist(struct session *se, const char *name, int *num) { int i; struct termlist_score **tl = 0; - session_enter(s); - for (i = 0; i < s->num_termlists; i++) - if (!strcmp((const char *) s->termlists[i].name, name)) + session_enter(se); + for (i = 0; i < se->num_termlists; i++) + if (!strcmp((const char *) se->termlists[i].name, name)) { - tl = termlist_highscore(s->termlists[i].termlist, num); + tl = termlist_highscore(se->termlists[i].termlist, num); break; } - session_leave(s); + session_leave(se); return tl; } @@ -787,50 +788,49 @@ void report_nmem_stats(void) } #endif -struct record_cluster *show_single_start(struct session *s, const char *id, +struct record_cluster *show_single_start(struct session *se, const char *id, struct record_cluster **prev_r, struct record_cluster **next_r) { struct record_cluster *r; - session_enter(s); - reclist_enter(s->reclist); + session_enter(se); + reclist_enter(se->reclist); *prev_r = 0; *next_r = 0; - while ((r = reclist_read_record(s->reclist))) + while ((r = reclist_read_record(se->reclist))) { if (!strcmp(r->recid, id)) { - *next_r = reclist_read_record(s->reclist); + *next_r = reclist_read_record(se->reclist); break; } *prev_r = r; } - reclist_leave(s->reclist); + reclist_leave(se->reclist); if (!r) - session_leave(s); + session_leave(se); return r; } -void show_single_stop(struct session *s, struct record_cluster *rec) +void show_single_stop(struct session *se, struct record_cluster *rec) { - session_leave(s); + session_leave(se); } -struct record_cluster **show_range_start(struct session *s, +struct record_cluster **show_range_start(struct session *se, struct reclist_sortparms *sp, int start, int *num, int *total, Odr_int *sumhits) { - struct record_cluster **recs = nmem_malloc(s->nmem, *num - * sizeof(struct record_cluster *)); + struct record_cluster **recs; struct reclist_sortparms *spp; int i; #if USE_TIMING yaz_timing_t t = yaz_timing_create(); #endif - - session_enter(s); - if (!s->relevance) + session_enter(se); + recs = nmem_malloc(se->nmem, *num * sizeof(struct record_cluster *)); + if (!se->relevance) { *num = 0; *total = 0; @@ -842,17 +842,17 @@ struct record_cluster **show_range_start(struct session *s, for (spp = sp; spp; spp = spp->next) if (spp->type == Metadata_sortkey_relevance) { - relevance_prepare_read(s->relevance, s->reclist); + relevance_prepare_read(se->relevance, se->reclist); break; } - reclist_sort(s->reclist, sp); + reclist_sort(se->reclist, sp); - reclist_enter(s->reclist); - *total = reclist_get_num_records(s->reclist); - *sumhits = s->total_hits; + reclist_enter(se->reclist); + *total = reclist_get_num_records(se->reclist); + *sumhits = se->total_hits; for (i = 0; i < start; i++) - if (!reclist_read_record(s->reclist)) + if (!reclist_read_record(se->reclist)) { *num = 0; recs = 0; @@ -861,7 +861,7 @@ struct record_cluster **show_range_start(struct session *s, for (i = 0; i < *num; i++) { - struct record_cluster *r = reclist_read_record(s->reclist); + struct record_cluster *r = reclist_read_record(se->reclist); if (!r) { *num = i; @@ -869,7 +869,7 @@ struct record_cluster **show_range_start(struct session *s, } recs[i] = r; } - reclist_leave(s->reclist); + reclist_leave(se->reclist); } #if USE_TIMING yaz_timing_stop(t); @@ -881,9 +881,9 @@ struct record_cluster **show_range_start(struct session *s, return recs; } -void show_range_stop(struct session *s, struct record_cluster **recs) +void show_range_stop(struct session *se, struct record_cluster **recs) { - session_leave(s); + session_leave(se); } void statistics(struct session *se, struct statistics *stat) @@ -1172,14 +1172,10 @@ int ingest_record(struct client *cl, const char *rec, xmlFreeDoc(xdoc); return -1; } - client_unlock(cl); session_enter(se); - client_lock(cl); if (client_get_session(cl) == se) ret = ingest_to_cluster(cl, xdoc, root, record_no, mergekey_norm); - client_unlock(cl); session_leave(se); - client_lock(cl); xmlFreeDoc(xdoc); return ret;