Merge branch 'master' into session_lock session_lock
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 16 Jul 2013 13:53:56 +0000 (15:53 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 16 Jul 2013 13:53:56 +0000 (15:53 +0200)
perf/bash/par.sh
src/client.c
src/connection.c
src/http_command.c
src/ppmutex.c
src/ppmutex.h
src/session.c
src/session.h
test/test_http.urls

index 7072a3f..83f7e56 100755 (executable)
@@ -2,9 +2,9 @@
 DELAY=0.001
 WAIT=5
 NUMBER=5
-ROUNDS=5
+ROUNDS=500
 PORT=9004
-SERVICE=perf_t
+SERVICE=perf
 SHUTDOWN=1
 HOST=127.0.0.1
 if test -n "$1"; then
index 662937f..e67b87b 100644 (file)
@@ -114,7 +114,6 @@ struct client {
     enum client_state state;
     struct show_raw *show_raw;
     ZOOM_resultset resultset;
-    YAZ_MUTEX mutex;
     int ref_count;
     char *id;
     facet_limits_t facet_limits;
@@ -497,18 +496,16 @@ static void ingest_raw_record(struct client *cl, ZOOM_record rec)
 void client_check_preferred_watch(struct client *cl)
 {
     struct session *se = cl->session;
+
     yaz_log(YLOG_DEBUG, "client_check_preferred_watch: %s ", client_get_id(cl));
     if (se)
     {
-        client_unlock(cl);
-        /* TODO possible threading issue. Session can have been destroyed */
-        if (session_is_preferred_clients_ready(se)) {
+        assert(cl->session);
+        if (session_is_preferred_clients_ready(se))
             session_alert_watch(se, SESSION_WATCH_SHOW_PREF);
-        }
         else
             yaz_log(YLOG_DEBUG, "client_check_preferred_watch: Still locked on preferred targets.");
-
-        client_lock(cl);
+        assert(cl->session);
     }
     else
         yaz_log(YLOG_WARN, "client_check_preferred_watch: %s. No session!", client_get_id(cl));
@@ -551,17 +548,13 @@ void client_search_response(struct client *cl)
 void client_got_records(struct client *cl)
 {
     struct session *se = cl->session;
-    if (se)
+
+    if (reclist_get_num_records(se->reclist) > 0)
     {
-        if (reclist_get_num_records(se->reclist) > 0)
-        {
-            client_unlock(cl);
-            session_alert_watch(se, SESSION_WATCH_SHOW);
-            session_alert_watch(se, SESSION_WATCH_BYTARGET);
-            session_alert_watch(se, SESSION_WATCH_TERMLIST);
-            session_alert_watch(se, SESSION_WATCH_RECORD);
-            client_lock(cl);
-        }
+        session_alert_watch(se, SESSION_WATCH_SHOW);
+        session_alert_watch(se, SESSION_WATCH_BYTARGET);
+        session_alert_watch(se, SESSION_WATCH_TERMLIST);
+        session_alert_watch(se, SESSION_WATCH_RECORD);
     }
 }
 
@@ -989,8 +982,6 @@ struct client *client_create(const char *id)
     cl->show_raw = 0;
     cl->resultset = 0;
     cl->suggestions = 0;
-    cl->mutex = 0;
-    pazpar2_mutex_create(&cl->mutex, "client");
     cl->preferred = 0;
     cl->ref_count = 1;
     cl->facet_limits = 0;
@@ -1004,19 +995,9 @@ struct client *client_create(const char *id)
     return cl;
 }
 
-void client_lock(struct client *c)
-{
-    yaz_mutex_enter(c->mutex);
-}
-
-void client_unlock(struct client *c)
-{
-    yaz_mutex_leave(c->mutex);
-}
-
 void client_incref(struct client *c)
 {
-    pazpar2_incref(&c->ref_count, c->mutex);
+    c->ref_count++;
     yaz_log(YLOG_DEBUG, "client_incref c=%p %s cnt=%d",
             c, client_get_id(c), c->ref_count);
 }
@@ -1027,7 +1008,7 @@ int client_destroy(struct client *c)
     {
         yaz_log(YLOG_DEBUG, "client_destroy c=%p %s cnt=%d",
                 c, client_get_id(c), c->ref_count);
-        if (!pazpar2_decref(&c->ref_count, c->mutex))
+        if (--c->ref_count == 0)
         {
             xfree(c->pquery);
             c->pquery = 0;
@@ -1047,7 +1028,6 @@ int client_destroy(struct client *c)
             {
                 ZOOM_resultset_destroy(c->resultset);
             }
-            yaz_mutex_destroy(&c->mutex);
             xfree(c);
             client_use(-1);
             return 1;
@@ -1661,12 +1641,6 @@ int client_get_maxrecs(struct client *cl)
     return cl->maxrecs;
 }
 
-void client_set_preferred(struct client *cl, int v)
-{
-    cl->preferred = v;
-}
-
-
 struct suggestions* client_suggestions_create(const char* suggestions_string)
 {
     int i;
index d5b5be2..5a5f207 100644 (file)
@@ -199,7 +199,7 @@ static struct connection *connection_create(struct client *cl,
     return co;
 }
 
-static void non_block_events(struct connection *co)
+static void non_block_events_unlocked(struct connection *co)
 {
     int got_records = 0;
     IOCHAN iochan = co->iochan;
@@ -280,11 +280,20 @@ static void non_block_events(struct connection *co)
     }
 }
 
+static void non_block_events(struct client *cl, struct connection *co)
+{
+    session_enter_rw(client_get_session(cl), "non_block_events");
+    non_block_events_unlocked(co);
+    session_leave_rw(client_get_session(cl), "non_block_events");
+}
+
 void connection_continue(struct connection *co)
 {
     int r = ZOOM_connection_exec_task(co->link);
     if (!r)
-        non_block_events(co);
+    {
+        non_block_events_unlocked(co);
+    }
     else
     {
         iochan_setflags(co->iochan, ZOOM_connection_get_mask(co->link));
@@ -313,9 +322,6 @@ static void connection_handler(IOCHAN iochan, int event)
     else if (event & EVENT_TIMEOUT)
     {
         ZOOM_connection_fire_event_timeout(co->link);
-        client_lock(cl);
-        non_block_events(co);
-        client_unlock(cl);
 
         remove_connection_from_host(co);
         yaz_mutex_leave(host->mutex);
@@ -325,13 +331,11 @@ static void connection_handler(IOCHAN iochan, int event)
     {
         yaz_mutex_leave(host->mutex);
 
-        client_lock(cl);
-        non_block_events(co);
+        non_block_events(cl, co);
 
         ZOOM_connection_fire_event_socket(co->link, event);
 
-        non_block_events(co);
-        client_unlock(cl);
+        non_block_events(cl, co);
 
         if (co->link)
         {
index 30de3d8..759d900 100644 (file)
@@ -165,7 +165,7 @@ struct http_session *http_session_create(struct conf_service *service,
     char tmp_str[50];
 
     sprintf(tmp_str, "session#%u", sesid);
-    r->psession = new_session(nmem, service, sesid);
+    r->psession = session_create(nmem, service, sesid);
     r->session_id = sesid;
     r->timestamp = 0;
     r->nmem = nmem;
@@ -867,7 +867,9 @@ static void cmd_bytarget(struct http_channel *c)
             return;
         }
     }
+    session_enter_ro(s->psession, "cmd_bytarget");
     bytarget_response(c, s, status_message);
+    session_leave_ro(s->psession, "cmd_bytarget");
     release_session(c, s);
 }
 
@@ -1169,7 +1171,6 @@ static void show_records(struct http_channel *c, struct http_session *s,
     {
         error(rs, PAZPAR2_MALFORMED_PARAMETER_VALUE, "sort");
         return;
-
     }
 
     rl = show_range_start(s->psession, sp, startn, &numn, &total,
@@ -1219,7 +1220,6 @@ static void show_records(struct http_channel *c, struct http_session *s,
     }
 
     show_range_stop(s->psession, rl);
-
     response_close(c, "show");
 }
 
@@ -1332,7 +1332,9 @@ static void cmd_show(struct http_channel *c)
             }
         }
     }
+    session_enter_ro(s->psession, "show_records");
     show_records(c, s, status);
+    session_leave_ro(s->psession, "show_records");
     release_session(c, s);
 }
 
index 8212653..2882bac 100644 (file)
@@ -43,6 +43,96 @@ void pazpar2_mutex_create(YAZ_MUTEX *p, const char *name)
     yaz_mutex_set_name(*p, ppmutex_level, name);
 }
 
+void pazpar2_lock_rdwr_init(Pazpar2_lock_rdwr *p)
+{
+    p->readers_reading = 0;
+    p->writers_writing = 0;
+#if YAZ_POSIX_THREADS
+    pthread_mutex_init(&p->mutex, 0);
+    pthread_cond_init(&p->lock_free, 0);
+#endif
+}
+
+void pazpar2_lock_rdwr_destroy(Pazpar2_lock_rdwr *p)
+{
+    assert (p->readers_reading == 0);
+    assert (p->writers_writing == 0);
+#if YAZ_POSIX_THREADS
+    pthread_mutex_destroy(&p->mutex);
+    pthread_cond_destroy(&p->lock_free);
+#endif
+}
+
+void pazpar2_lock_rdwr_rlock(Pazpar2_lock_rdwr *p)
+{
+#if YAZ_POSIX_THREADS
+    pthread_mutex_lock(& p->mutex);
+    while (p->writers_writing)
+       pthread_cond_wait(&p->lock_free, &p->mutex);
+    p->readers_reading++;
+    pthread_mutex_unlock(&p->mutex);
+#endif
+}
+
+void pazpar2_lock_rdwr_wlock(Pazpar2_lock_rdwr *p)
+{
+#if YAZ_POSIX_THREADS
+    pthread_mutex_lock(&p->mutex);
+    while (p->writers_writing || p->readers_reading)
+       pthread_cond_wait(&p->lock_free, &p->mutex);
+    p->writers_writing++;
+    pthread_mutex_unlock(&p->mutex);
+#endif
+}
+
+void pazpar2_lock_rdwr_upgrade(Pazpar2_lock_rdwr *p)
+{
+#if YAZ_POSIX_THREADS
+    assert(p->readers_reading > 0);
+    pthread_mutex_lock(&p->mutex);
+    --p->readers_reading;
+    while (p->writers_writing || p->readers_reading)
+       pthread_cond_wait(&p->lock_free, &p->mutex);
+    p->writers_writing++;
+    pthread_mutex_unlock(&p->mutex);
+#endif
+}
+
+void pazpar2_lock_rdwr_downgrade(Pazpar2_lock_rdwr *p)
+{
+#if YAZ_POSIX_THREADS
+    assert(p->writers_writing == 1);
+    pthread_mutex_lock(&p->mutex);
+    p->writers_writing--;
+    p->readers_reading++;
+    pthread_cond_broadcast(&p->lock_free);
+    pthread_mutex_unlock(&p->mutex);
+#endif
+}
+
+void pazpar2_lock_rdwr_runlock(Pazpar2_lock_rdwr *p)
+{
+#if YAZ_POSIX_THREADS
+    assert(p->readers_reading > 0);
+    pthread_mutex_lock(&p->mutex);
+    p->readers_reading--;
+    if (p->readers_reading == 0)
+        pthread_cond_signal(&p->lock_free);
+    pthread_mutex_unlock(&p->mutex);
+#endif
+}
+
+void pazpar2_lock_rdwr_wunlock(Pazpar2_lock_rdwr *p)
+{
+#if YAZ_POSIX_THREADS
+    assert(p->writers_writing == 1);
+    pthread_mutex_lock(&p->mutex);
+    p->writers_writing--;
+    pthread_cond_broadcast(&p->lock_free);
+    pthread_mutex_unlock(&p->mutex);
+#endif
+}
+
 /*
  * Local variables:
  * c-basic-offset: 4
index a4159ec..f47dfd9 100644 (file)
@@ -22,14 +22,36 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */
 
 #ifndef PAZPAR2_PPMUTEX_H
-#define PAZPAR2_PPMUTEXF_H
+#define PAZPAR2_PPMUTEX_H
 
 #include <yaz/mutex.h>
 
+#if YAZ_POSIX_THREADS
+#include <pthread.h>
+#endif
+
 void pazpar2_mutex_init(void);
 
 void pazpar2_mutex_create(YAZ_MUTEX *p, const char *name);
 
+typedef struct {
+    int readers_reading;
+    int writers_writing;
+#if YAZ_POSIX_THREADS
+    pthread_mutex_t mutex;
+    pthread_cond_t lock_free;
+#endif
+} Pazpar2_lock_rdwr;
+
+void pazpar2_lock_rdwr_init(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_destroy(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_rlock(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_wlock(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_runlock(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_wunlock(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_upgrade(Pazpar2_lock_rdwr *p);
+void pazpar2_lock_rdwr_downgrade(Pazpar2_lock_rdwr *p);
+
 #endif
 
 /*
index e3e0a0d..8481280 100644 (file)
@@ -135,18 +135,52 @@ static void log_xml_doc(xmlDoc *doc)
     xmlFree(result);
 }
 
-static void session_enter(struct session *s, const char *caller)
+void session_enter_ro(struct session *s, const char *caller)
 {
+    assert(s);
+    if (caller)
+        session_log(s, YLOG_LOG, "Session read lock by %s", caller);
+    pazpar2_lock_rdwr_rlock(&s->lock);
+}
+
+void session_enter_rw(struct session *s, const char *caller)
+{
+    assert(s);
+    if (caller)
+        session_log(s, YLOG_LOG, "Session write lock by %s", caller);
+    pazpar2_lock_rdwr_wlock(&s->lock);
+}
+
+void session_upgrade(struct session *s, const char *caller)
+{
+    assert(s);
+    if (caller)
+        session_log(s, YLOG_LOG, "Session upgrade lock by %s", caller);
+    pazpar2_lock_rdwr_upgrade(&s->lock);
+}
+
+void session_leave_ro(struct session *s, const char *caller)
+{
+    assert(s);
+    if (caller)
+        session_log(s, YLOG_LOG, "Session read unlock by %s", caller);
+    pazpar2_lock_rdwr_runlock(&s->lock);
+}
+
+void session_leave_rw(struct session *s, const char *caller)
+{
+    assert(s);
     if (caller)
-        session_log(s, YLOG_DEBUG, "Session lock by %s", caller);
-    yaz_mutex_enter(s->session_mutex);
+        session_log(s, YLOG_LOG, "Session write unlock by %s", caller);
+    pazpar2_lock_rdwr_wunlock(&s->lock);
 }
 
-static void session_leave(struct session *s, const char *caller)
+void session_downgrade(struct session *s, const char *caller)
 {
-    yaz_mutex_leave(s->session_mutex);
+    assert(s);
     if (caller)
-        session_log(s, YLOG_DEBUG, "Session unlock by %s", caller);
+        session_log(s, YLOG_LOG, "Session write unlock by %s", caller);
+    pazpar2_lock_rdwr_downgrade(&s->lock);
 }
 
 static void session_normalize_facet(struct session *s,
@@ -451,7 +485,6 @@ int session_set_watch(struct session *s, int what,
                       struct http_channel *chan)
 {
     int ret;
-    session_enter(s, "session_set_watch");
     if (s->watchlist[what].fun)
         ret = -1;
     else
@@ -463,14 +496,12 @@ int session_set_watch(struct session *s, int what,
                                                    session_watch_cancel);
         ret = 0;
     }
-    session_leave(s, "session_set_watch");
     return ret;
 }
 
 void session_alert_watch(struct session *s, int what)
 {
     assert(s);
-    session_enter(s, "session_alert_watch");
     if (s->watchlist[what].fun)
     {
         /* our watch is no longer associated with http_channel */
@@ -487,13 +518,10 @@ void session_alert_watch(struct session *s, int what)
         s->watchlist[what].data = 0;
         s->watchlist[what].obs = 0;
 
-        session_leave(s, "session_alert_watch");
         session_log(s, YLOG_DEBUG,
                     "Alert Watch: %d calling function: %p", what, fun);
         fun(data);
     }
-    else
-        session_leave(s,"session_alert_watch");
 }
 
 //callback for grep_databases
@@ -533,18 +561,14 @@ static void session_reset_active_clients(struct session *se,
 {
     struct client_list *l;
 
-    session_enter(se, "session_reset_active_clients");
     l = se->clients_active;
     se->clients_active = new_list;
-    session_leave(se, "session_reset_active_clients");
 
     while (l)
     {
         struct client_list *l_next = l->next;
 
-        client_lock(l->client);
         client_set_session(l->client, 0); /* mark client inactive */
-        client_unlock(l->client);
 
         xfree(l);
         l = l_next;
@@ -557,18 +581,14 @@ static void session_remove_cached_clients(struct session *se)
 
     session_reset_active_clients(se, 0);
 
-    session_enter(se, "session_remove_cached_clients");
     l = se->clients_cached;
     se->clients_cached = 0;
-    session_leave(se, "session_remove_cached_clients");
 
     while (l)
     {
         struct client_list *l_next = l->next;
-        client_lock(l->client);
         client_set_session(l->client, 0);
         client_set_database(l->client, 0);
-        client_unlock(l->client);
         client_destroy(l->client);
         xfree(l);
         l = l_next;
@@ -735,22 +755,22 @@ static void session_sort_unlocked(struct session *se,
 void session_sort(struct session *se, struct reclist_sortparms *sp,
                   const char *mergekey, const char *rank)
 {
-    //session_enter(se, "session_sort");
+    session_enter_rw(se, "session_sort");
     session_sort_unlocked(se, sp, mergekey, rank);
-    //session_leave(se, "session_sort");
+    session_leave_rw(se, "session_sort");
 }
 
-
-enum pazpar2_error_code session_search(struct session *se,
-                                       const char *query,
-                                       const char *startrecs,
-                                       const char *maxrecs,
-                                       const char *filter,
-                                       const char *limit,
-                                       const char **addinfo,
-                                       struct reclist_sortparms *sp,
-                                       const char *mergekey,
-                                       const char *rank)
+static
+enum pazpar2_error_code session_search_unlocked(struct session *se,
+                                                const char *query,
+                                                const char *startrecs,
+                                                const char *maxrecs,
+                                                const char *filter,
+                                                const char *limit,
+                                                const char **addinfo,
+                                                struct reclist_sortparms *sp,
+                                                const char *mergekey,
+                                                const char *rank)
 {
     int live_channels = 0;
     int no_working = 0;
@@ -762,13 +782,11 @@ enum pazpar2_error_code session_search(struct session *se,
 
     *addinfo = 0;
 
-    if (se->settings_modified) {
+    if (se->settings_modified)
         session_remove_cached_clients(se);
-    }
     else
         session_reset_active_clients(se, 0);
 
-    session_enter(se, "session_search");
     se->settings_modified = 0;
 
     if (mergekey)
@@ -787,23 +805,18 @@ enum pazpar2_error_code session_search(struct session *se,
 
     live_channels = select_targets(se, filter);
     if (!live_channels)
-    {
-        session_leave(se, "session_search");
         return PAZPAR2_NO_TARGETS;
-    }
 
     facet_limits_destroy(se->facet_limits);
     se->facet_limits = facet_limits_create(limit);
     if (!se->facet_limits)
     {
         *addinfo = "limit";
-        session_leave(se, "session_search");
         return PAZPAR2_MALFORMED_PARAMETER_VALUE;
     }
 
     l0 = se->clients_active;
     se->clients_active = 0;
-    session_leave(se, "session_search");
 
     for (l = l0; l; l = l->next)
     {
@@ -845,10 +858,28 @@ enum pazpar2_error_code session_search(struct session *se,
         else
             return PAZPAR2_NO_TARGETS;
     }
-    session_log(se, YLOG_LOG, "session_start_search done");
     return PAZPAR2_NO_ERROR;
 }
 
+enum pazpar2_error_code session_search(struct session *se,
+                                       const char *query,
+                                       const char *startrecs,
+                                       const char *maxrecs,
+                                       const char *filter,
+                                       const char *limit,
+                                       const char **addinfo,
+                                       struct reclist_sortparms *sp,
+                                       const char *mergekey,
+                                       const char *rank)
+{
+    enum pazpar2_error_code c;
+    session_enter_rw(se, "session_search");
+    c = session_search_unlocked(se, query, startrecs, maxrecs, filter,
+                                limit, addinfo, sp, mergekey, rank);
+    session_leave_rw(se, "session_search");
+    return c;
+}
+
 // Creates a new session_database object for a database
 static void session_init_databases_fun(void *context, struct database *db)
 {
@@ -946,6 +977,8 @@ void session_apply_setting(struct session *se, char *dbname, char *setting,
 void session_destroy(struct session *se)
 {
     struct session_database *sdb;
+
+    session_enter_rw(se, "session_destroy");
     session_log(se, YLOG_DEBUG, "Destroying");
     session_use(-1);
     session_remove_cached_clients(se);
@@ -964,22 +997,24 @@ void session_destroy(struct session *se)
     facet_limits_destroy(se->facet_limits);
     nmem_destroy(se->nmem);
     service_destroy(se->service);
-    yaz_mutex_destroy(&se->session_mutex);
+
+    session_leave_rw(se, "session_destroy");
+    pazpar2_lock_rdwr_destroy(&se->lock);
 }
 
 size_t session_get_memory_status(struct session *session) {
     size_t session_nmem;
     if (session == 0)
         return 0;
-    session_enter(session, "session_get_memory_status");
+    session_enter_ro(session, "session_get_memory_status");
     session_nmem = nmem_total(session->nmem);
-    session_leave(session, "session_get_memory_status");
+    session_leave_ro(session, "session_get_memory_status");
     return session_nmem;
 }
 
 
-struct session *new_session(NMEM nmem, struct conf_service *service,
-                            unsigned session_id)
+struct session *session_create(NMEM nmem, struct conf_service *service,
+                               unsigned session_id)
 {
     int i;
     struct session *session = nmem_malloc(nmem, sizeof(*session));
@@ -989,7 +1024,7 @@ struct session *new_session(NMEM nmem, struct conf_service *service,
     sprintf(tmp_str, "session#%u", session_id);
 
     session->session_id = session_id;
-    session_log(session, YLOG_DEBUG, "New");
+    session_log(session, YLOG_LOG, "new");
     session->service = service;
     session->relevance = 0;
     session->total_records = 0;
@@ -1014,8 +1049,9 @@ struct session *new_session(NMEM nmem, struct conf_service *service,
         session->watchlist[i].fun = 0;
     }
     session->normalize_cache = normalize_cache_create();
-    session->session_mutex = 0;
-    pazpar2_mutex_create(&session->session_mutex, tmp_str);
+
+    pazpar2_lock_rdwr_init(&session->lock);
+
     session_use(1);
     return session;
 }
@@ -1066,9 +1102,7 @@ static struct hitsbytarget *hitsbytarget_nb(struct session *se,
 struct hitsbytarget *get_hitsbytarget(struct session *se, int *count, NMEM nmem)
 {
     struct hitsbytarget *p;
-    session_enter(se, "get_hitsbytarget");
     p = hitsbytarget_nb(se, count, nmem);
-    session_leave(se, "get_hitsbytarget");
     return p;
 }
 
@@ -1151,7 +1185,7 @@ void perform_termlist(struct http_channel *c, struct session *se,
 
     nmem_strsplit(nmem_tmp, ",", name, &names, &num_names);
 
-    session_enter(se, "perform_termlist");
+    session_enter_ro(se, "perform_termlist");
 
     for (j = 0; j < num_names; j++)
     {
@@ -1214,7 +1248,7 @@ void perform_termlist(struct http_channel *c, struct session *se,
             wrbuf_puts(c->wrbuf, "\"/>\n");
         }
     }
-    session_leave(se, "perform_termlist");
+    session_leave_ro(se, "perform_termlist");
     nmem_destroy(nmem_tmp);
 }
 
@@ -1237,7 +1271,7 @@ struct record_cluster *show_single_start(struct session *se, const char *id,
 {
     struct record_cluster *r = 0;
 
-    session_enter(se, "show_single_start");
+    session_enter_ro(se, "show_single_start");
     *prev_r = 0;
     *next_r = 0;
     reclist_limit(se->reclist, se);
@@ -1254,13 +1288,13 @@ struct record_cluster *show_single_start(struct session *se, const char *id,
     }
     reclist_leave(se->reclist);
     if (!r)
-        session_leave(se, "show_single_start");
+        session_leave_ro(se, "show_single_start");
     return r;
 }
 
 void show_single_stop(struct session *se, struct record_cluster *rec)
 {
-    session_leave(se, "show_single_stop");
+    session_leave_ro(se, "show_single_stop");
 }
 
 
@@ -1310,7 +1344,6 @@ struct record_cluster **show_range_start(struct session *se,
 #if USE_TIMING
     yaz_timing_t t = yaz_timing_create();
 #endif
-    session_enter(se, "show_range_start");
     *sumhits = 0;
     *approx_hits = 0;
     *total = 0;
@@ -1381,16 +1414,15 @@ struct record_cluster **show_range_start(struct session *se,
         session_log(se, YLOG_LOG, "can not fetch more");
     else
     {
-        show_range_stop(se, recs);
         session_log(se, YLOG_LOG, "fetching more in progress");
         if (session_set_watch(se, SESSION_WATCH_SHOW,
                               show_records_ready, chan, chan))
         {
             session_log(se, YLOG_WARN, "Ignoring show block");
-            session_enter(se, "show_range_start");
         }
         else
         {
+            show_range_stop(se, recs);
             session_log(se, YLOG_LOG, "session watch OK");
             return 0;
         }
@@ -1400,7 +1432,6 @@ struct record_cluster **show_range_start(struct session *se,
 
 void show_range_stop(struct session *se, struct record_cluster **recs)
 {
-    session_leave(se, "show_range_stop");
 }
 
 void statistics(struct session *se, struct statistics *stat)
@@ -1714,10 +1745,10 @@ int ingest_record(struct client *cl, const char *rec,
         xmlFreeDoc(xdoc);
         return -1;
     }
-    session_enter(se, "ingest_record");
-    if (client_get_session(cl) == se && se->relevance)
+    assert(client_get_session(cl) == se);
+
+    if (se->relevance)
         ret = ingest_to_cluster(cl, xdoc, root, record_no, mergekey_norm);
-    session_leave(se, "ingest_record");
 
     xmlFreeDoc(xdoc);
     return ret;
index 732efbc..0845f0d 100644 (file)
@@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include "termlists.h"
 #include "reclists.h"
 #include "http.h"
+#include "ppmutex.h"
 
 struct record;
 struct client;
@@ -119,7 +120,7 @@ struct session {
     int number_of_warnings_unknown_elements;
     int number_of_warnings_unknown_metadata;
     normalize_cache_t normalize_cache;
-    YAZ_MUTEX session_mutex;
+    Pazpar2_lock_rdwr lock;
     unsigned session_id;
     int settings_modified;
     facet_limits_t facet_limits;
@@ -155,9 +156,10 @@ struct hitsbytarget {
 };
 
 struct hitsbytarget *get_hitsbytarget(struct session *s, int *count, NMEM nmem);
-struct session *new_session(NMEM nmem, struct conf_service *service,
-                            unsigned session_id);
+struct session *session_create(NMEM nmem, struct conf_service *service,
+                               unsigned session_id);
 int sessions_count(void);
+
 void session_destroy(struct session *s);
 void session_init_databases(struct session *s);
 void statistics(struct session *s, struct statistics *stat);
@@ -201,6 +203,13 @@ void add_facet(struct session *s, const char *type, const char *value, int count
 int session_check_cluster_limit(struct session *se, struct record_cluster *rec);
 
 void perform_termlist(struct http_channel *c, struct session *se, const char *name, int num, int version);
+
+void session_enter_ro(struct session *s, const char *caller);
+void session_leave_ro(struct session *s, const char *caller);
+
+void session_enter_rw(struct session *s, const char *caller);
+void session_leave_rw(struct session *s, const char *caller);
+
 void session_log(struct session *s, int level, const char *fmt, ...)
 #ifdef __GNUC__
     __attribute__ ((format (printf, 3, 4)))
index 3b4f7e9..0bae2aa 100644 (file)
@@ -68,7 +68,7 @@ http://localhost:9763/search.pz2?session=9&command=search&query=greece&limit=aut
 http://localhost:9763/search.pz2?session=9&command=bytarget
 http://localhost:9763/search.pz2?session=9&command=show
 http://localhost:9763/search.pz2?session=9&command=search&query=greece&limit=author%3Dadam\,+james%7Cother_author
-http://localhost:9763/search.pz2?session=9&command=bytarget
+http://localhost:9763/search.pz2?session=9&command=bytarget&block=1
 http://localhost:9763/search.pz2?session=9&command=show
 http://localhost:9763/search.pz2?session=9&command=search&query=computer&limit=Mysubject%3DRailroads
 http://localhost:9763/search.pz2?session=9&command=show&block=1