Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/pazpar2
authorDennis Schafroth <dennis@indexdata.com>
Fri, 12 Mar 2010 13:55:04 +0000 (14:55 +0100)
committerDennis Schafroth <dennis@indexdata.com>
Fri, 12 Mar 2010 13:55:04 +0000 (14:55 +0100)
1  2 
src/client.c
src/http_command.c

diff --combined src/client.c
@@@ -64,6 -64,7 +64,7 @@@ Foundation, Inc., 51 Franklin St, Fift
  #include "connection.h"
  #include "settings.h"
  #include "relevance.h"
+ #include "incref.h"
  
  /** \brief Represents client state for a connection to one search target */
  struct client {
@@@ -81,6 -82,8 +82,8 @@@
      struct show_raw *show_raw;
      struct client *next;     // next client in session or next in free list
      ZOOM_resultset resultset;
+     YAZ_MUTEX mutex;
+     int ref_count;
  };
  
  struct show_raw {
@@@ -119,12 -122,14 +122,14 @@@ void client_set_state(struct client *cl
      cl->state = st;
      /* no need to check for all client being non-active if this one
         already is. Note that session_active_clients also LOCKS session */
+ #if 0
      if (!client_is_active(cl) && cl->session)
      {
          int no_active = session_active_clients(cl->session);
          if (no_active == 0)
              session_alert_watch(cl->session, SESSION_WATCH_SHOW);
      }
+ #endif
  }
  
  static void client_show_raw_error(struct client *cl, const char *addinfo);
@@@ -344,11 -349,6 +349,11 @@@ static int nativesyntax_to_type(struct 
          {
              strcpy(type, "xml");
          }
 +        else if (!strncmp(s, "txml", 4))
 +        {
 +            const char *cp = strchr(s, ';');
 +            yaz_snprintf(type, 80, "txml; charset=%s", cp ? cp+1 : "marc-8s");
 +        }
          else
              return -1;
          return 0;
                  strcpy(type, "xml");
                  return 0;
              }
 +            else if (!strcmp(syntax, "TXML"))
 +                {
 +                    strcpy(type, "txml");
 +                    return 0;
 +                }
              else if (!strcmp(syntax, "USmarc") || !strcmp(syntax, "MARC21"))
              {
                  strcpy(type, "xml; charset=marc8-s");
@@@ -404,23 -399,32 +409,32 @@@ void client_search_response(struct clie
      struct session *se = cl->session;
      ZOOM_connection link = connection_get_link(co);
      ZOOM_resultset resultset = cl->resultset;
-     const char *error, *addinfo;
+     const char *error, *addinfo = 0;
+     
      if (ZOOM_connection_error(link, &error, &addinfo))
      {
          cl->hits = 0;
          client_set_state(cl, Client_Error);
          yaz_log(YLOG_WARN, "Search error %s (%s): %s",
-             error, addinfo, client_get_url(cl));
+                 error, addinfo, client_get_url(cl));
      }
      else
      {
          cl->record_offset = cl->startrecs;
          cl->hits = ZOOM_resultset_size(resultset);
-         se->total_hits += cl->hits;
+         if (se)
+             se->total_hits += cl->hits;
      }
  }
  
+ void client_got_records(struct client *cl)
+ {
+     if (cl->session)
+     {
+         session_alert_watch(cl->session, SESSION_WATCH_SHOW);
+         session_alert_watch(cl->session, SESSION_WATCH_RECORD);
+     }
+ }
  
  void client_record_response(struct client *cl)
  {
              if ((rec = ZOOM_resultset_record(resultset, offset)))
              {
                  cl->record_offset++;
-                 if (ZOOM_record_error(rec, &msg, &addinfo, 0))
+                 if (cl->session == 0)
+                     ;
+                 else if (ZOOM_record_error(rec, &msg, &addinfo, 0))
                      yaz_log(YLOG_WARN, "Record error %s (%s): %s (rec #%d)",
                              error, addinfo, client_get_url(cl),
                              cl->record_offset);
                      char type[80];
                      if (nativesyntax_to_type(sdb, type, rec))
                          yaz_log(YLOG_WARN, "Failed to determine record type");
-                     if ((xmlrec = ZOOM_record_get(rec, type, NULL)))
+                     xmlrec = ZOOM_record_get(rec, type, NULL);
+                     if (!xmlrec)
+                         yaz_log(YLOG_WARN, "ZOOM_record_get failed from %s",
+                                 client_get_url(cl));
+                     else
                      {
-                         if (!ingest_record(cl, xmlrec, cl->record_offset, nmem))
-                         {
-                             session_alert_watch(cl->session, SESSION_WATCH_SHOW);
-                             session_alert_watch(cl->session, SESSION_WATCH_RECORD);
-                         }
-                         else
-                             yaz_log(YLOG_WARN, "Failed to ingest");
+                         if (ingest_record(cl, xmlrec, cl->record_offset, nmem))
+                             yaz_log(YLOG_WARN, "Failed to ingest from %s",
+                                     client_get_url(cl));
                      }
-                     else
-                         yaz_log(YLOG_WARN, "Failed to extract ZOOM record");
                      nmem_destroy(nmem);
                  }
              }
              else
              {
@@@ -589,35 -592,55 +602,55 @@@ struct client *client_create(void
      r->show_raw = 0;
      r->resultset = 0;
      r->next = 0;
+     r->mutex = 0;
+     yaz_mutex_create(&r->mutex);
+     r->ref_count = 1;
+     
      return r;
  }
  
- void client_destroy(struct client *c)
+ void client_incref(struct client *c)
  {
-     struct session *se = c->session;
-     if (c == se->clients)
-         se->clients = c->next;
-     else
+     pazpar2_incref(&c->ref_count, c->mutex);
+     yaz_log(YLOG_DEBUG, "client_incref %s %d", client_get_url(c), c->ref_count);
+ }
+ int client_destroy(struct client *c)
+ {
+     if (c)
      {
-         struct client *cc;
-         for (cc = se->clients; cc && cc->next != c; cc = cc->next)
-             ;
-         if (cc)
-             cc->next = c->next;
+         yaz_log(YLOG_DEBUG, "client_destroy %s %d",
+                 client_get_url(c), c->ref_count);
+         if (!pazpar2_decref(&c->ref_count, c->mutex))
+         {
+             c->next = 0;
+             xfree(c->pquery);
+             c->pquery = 0;
+             xfree(c->cqlquery);
+             c->cqlquery = 0;
+             ZOOM_resultset_destroy(c->resultset);
+             yaz_mutex_destroy(&c->mutex);
+             xfree(c);
+             return 1;
+         }
      }
-     xfree(c->pquery);
-     xfree(c->cqlquery);
-     if (c->connection)
-         connection_release(c->connection);
-     ZOOM_resultset_destroy(c->resultset);
-     xfree(c);
+     return 0;
  }
  
  void client_set_connection(struct client *cl, struct connection *con)
  {
-     cl->connection = con;
+     if (con)
+     {
+         assert(cl->connection == 0);
+         cl->connection = con;
+         client_incref(cl);
+     }
+     else
+     {
+         cl->connection = con;
+         client_destroy(cl);
+     }
  }
  
  void client_disconnect(struct client *cl)
@@@ -765,6 -788,30 +798,30 @@@ int client_parse_query(struct client *c
      return 0;
  }
  
+ void client_remove_from_session(struct client *c)
+ {
+     struct session *se;
+     client_incref(c);
+     se = c->session;
+     assert(se);
+     if (se)
+     {
+         struct client **ccp = &se->clients;
+         
+         while (*ccp && *ccp != c)
+             ccp = &(*ccp)->next;
+         assert(*ccp == c);
+         *ccp = c->next;
+         
+         c->database = 0;
+         c->session = 0;
+         c->next = 0;
+     }
+     client_destroy(c);
+ }
  void client_set_session(struct client *cl, struct session *se)
  {
      cl->session = se;
@@@ -820,7 -867,10 +877,10 @@@ struct host *client_get_host(struct cli
  
  const char *client_get_url(struct client *cl)
  {
-     return client_get_database(cl)->database->url;
+     if (cl->database)
+         return client_get_database(cl)->database->url;
+     else
+         return "NOURL";
  }
  
  void client_set_maxrecs(struct client *cl, int v)
diff --combined src/http_command.c
@@@ -107,7 -107,7 +107,7 @@@ struct http_session *http_session_creat
      r->session_id = 0;
      r->timestamp = 0;
      r->nmem = nmem;
-     r->destroy_counter = r->activity_counter;
+     r->destroy_counter = r->activity_counter = 0;
      r->http_sessions = http_sessions;
  
      yaz_mutex_enter(http_sessions->mutex);
@@@ -162,10 -162,6 +162,10 @@@ void http_session_destroy(struct http_s
          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);
 +    }
 +
  }
  
  static const char *get_msg(enum pazpar2_error_code code)