+yf::SRUtoZ3950::Frontend::~Frontend()
+{
+}
+
+
+yf::SRUtoZ3950::FrontendPtr yf::SRUtoZ3950::Impl::get_frontend(
+ mp::Package &package)
+{
+ boost::mutex::scoped_lock lock(m_mutex_session);
+
+ std::map<mp::Session,yf::SRUtoZ3950::FrontendPtr>::iterator it;
+
+ while (true)
+ {
+ it = m_clients.find(package.session());
+ if (it == m_clients.end())
+ break;
+
+ if (!it->second->m_in_use)
+ {
+ it->second->m_in_use = true;
+ return it->second;
+ }
+ m_cond_session_ready.wait(lock);
+ }
+ FrontendPtr f(new Frontend);
+ m_clients[package.session()] = f;
+ f->m_in_use = true;
+ return f;
+}
+
+void yf::SRUtoZ3950::Impl::release_frontend(mp::Package &package)
+{
+ boost::mutex::scoped_lock lock(m_mutex_session);
+ std::map<mp::Session,FrontendPtr>::iterator it;
+
+ it = m_clients.find(package.session());
+ if (it != m_clients.end())
+ {
+ if (package.session().is_closed())
+ {
+ m_clients.erase(it);
+ }
+ else
+ {
+ it->second->m_in_use = false;
+ }
+ m_cond_session_ready.notify_all();
+ }
+}
+
+void yf::SRUtoZ3950::Impl::process(mp::Package &package)
+{
+ FrontendPtr f = get_frontend(package);
+
+ Z_GDU *zgdu_req = package.request().get();
+
+ if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request)
+ {
+ if (zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_url_mutex);
+ while (1)
+ {
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+ if (it == m_active_urls.end())
+ {
+ m_active_urls[path] = 1;
+ break;
+ }
+ yaz_log(YLOG_LOG, "Waiting for %s to complete", path);
+ m_cond_url_ready.wait(lock);
+ }
+ }
+ sru(package, zgdu_req);
+ if (zgdu_req && zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_url_mutex);
+
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+
+ m_active_urls.erase(it);
+ m_cond_url_ready.notify_all();
+ }
+ }
+ else
+ {
+ package.move();
+ }
+ release_frontend(package);
+}
+
+static void interpret_default_diag(int *error,
+ const char **addinfo,
+ Z_DefaultDiagFormat *r)
+{
+ *error = *r->condition;
+ *addinfo = r->u.v2Addinfo;
+}
+
+static void interpret_init_diag2(int *error,
+ const char **addinfo,
+ Z_DiagnosticFormat *diag)
+{
+ if (diag->num > 0)
+ {
+ Z_DiagnosticFormat_s *ds = diag->elements[0];
+ if (ds->which == Z_DiagnosticFormat_s_defaultDiagRec)
+ interpret_default_diag(error, addinfo, ds->u.defaultDiagRec);
+ }
+}
+
+static void interpret_init_diag(int *error,
+ const char **addinfo,
+ Z_InitResponse *initrs)
+{
+ Z_External *uif = initrs->userInformationField;
+ if (uif && uif->which == Z_External_userInfo1)
+ {
+ int i;
+ Z_OtherInformation *ui = uif->u.userInfo1;
+ for (i = 0; i < ui->num_elements; i++)
+ {
+ Z_OtherInformationUnit *unit = ui->list[i];
+ if (unit->which == Z_OtherInfo_externallyDefinedInfo &&
+ unit->information.externallyDefinedInfo &&
+ unit->information.externallyDefinedInfo->which ==
+ Z_External_diag1)
+ {
+ interpret_init_diag2(
+ error, addinfo,
+ unit->information.externallyDefinedInfo->u.diag1);
+ }
+ }
+ }
+}
+
+bool
+yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package,