Merge branch 'master' into channel_list_mutex
authorDennis Schafroth <dennis@indexdata.com>
Thu, 29 Apr 2010 08:42:32 +0000 (10:42 +0200)
committerDennis Schafroth <dennis@indexdata.com>
Thu, 29 Apr 2010 08:42:32 +0000 (10:42 +0200)
etc/tmarcxml.xsl [deleted file]
perf/bash/.gitignore
perf/bash/par.sh
src/eventl.c
src/http_command.c
src/sel_thread.c
src/session.c

diff --git a/etc/tmarcxml.xsl b/etc/tmarcxml.xsl
deleted file mode 100644 (file)
index 42ae103..0000000
+++ /dev/null
@@ -1,838 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-       xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:pz="http://www.indexdata.com/pazpar2/1.0"
-       xmlns:tmarc="http://www.indexdata.com/MARC21/turboxml">
-
-       <xsl:output indent="yes" method="xml" version="1.0"
-               encoding="UTF-8" />
-
-       <!-- Extract metadata from MARC21/USMARC from streamlined marcxml format 
-               http://www.loc.gov/marc/bibliographic/ecbdhome.html -->
-       <xsl:template name="record-hook" />
-
-
-       <xsl:template match="/">
-                       <xsl:apply-templates />
-       </xsl:template>
-
-       <xsl:template match="tmarc:r">
-               <xsl:variable name="title_medium" select="tmarc:d245/tmarc:sh" />
-               <xsl:variable name="journal_title" select="tmarc:d773/tmarc:st" />
-               <xsl:variable name="electronic_location_url" select="tmarc:d856/tmarc:su" />
-               <xsl:variable name="fulltext_a" select="tmarc:d900/tmarc:sa" />
-               <xsl:variable name="fulltext_b" select="tmarc:d900/tmarc:sb" />
-               <!-- Does not always hit the right substring. The field is not always fixed-width? -->
-               <xsl:variable name="control_lang" select="substring(tmarc:c008, 36, 3)" />
-               <xsl:variable name="contains110" select="tmarc:d110" />
-               <xsl:variable name="hasAuthorFields" select="tmarc:d100 or tmarc:d111" />
-
-               <xsl:variable name="medium">
-                       <xsl:choose>
-                               <xsl:when test="$title_medium">
-                                       <xsl:value-of select="translate($title_medium, ' []/', '')" />
-                               </xsl:when>
-                               <xsl:when test="$fulltext_a">
-                                       <xsl:text>electronic resource</xsl:text>
-                               </xsl:when>
-                               <xsl:when test="$fulltext_b">
-                                       <xsl:text>electronic resource</xsl:text>
-                               </xsl:when>
-                               <xsl:when test="$journal_title">
-                                       <xsl:text>article</xsl:text>
-                               </xsl:when>
-                               <xsl:otherwise>
-                                       <xsl:text>book</xsl:text>
-                               </xsl:otherwise>
-                       </xsl:choose>
-               </xsl:variable>
-
-               <pz:record>
-<!--
-                       <xsl:attribute name="mergekey">
-        <xsl:text>title </xsl:text>
-       <xsl:value-of select="tmarc:d245/tmarc:sa" />
-       <xsl:text> author </xsl:text>
-       <xsl:value-of select="tmarc:d100/tmarc:sa" />
-       <xsl:text> medium </xsl:text>
-       <xsl:value-of select="$medium" />
-      </xsl:attribute>
-  -->
-
-                       <xsl:for-each select="tmarc:c001">
-                               <pz:metadata type="id">
-                                       <xsl:value-of select="." />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d010">
-                               <pz:metadata type="lccn">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d020">
-                               <pz:metadata type="isbn">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d022">
-                               <pz:metadata type="issn">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d027">
-                               <pz:metadata type="tech-rep-nr">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d035">
-                               <pz:metadata type="system-control-nr">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d100">
-                               <pz:metadata type="author">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="author-title">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                               <pz:metadata type="author-date">
-                                       <xsl:value-of select="tmarc:sd" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d110">
-                               <pz:metadata type="corporate-name">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="corporate-location">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                               <pz:metadata type="corporate-date">
-                                       <xsl:value-of select="tmarc:sd" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d111">
-                               <pz:metadata type="meeting-name">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="meeting-location">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                               <pz:metadata type="meeting-date">
-                                       <xsl:value-of select="tmarc:sd" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d260">
-                               <pz:metadata type="date">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d130">
-                               <pz:metadata type="title-uniform">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="title-uniform-media">
-                                       <xsl:value-of select="tmarc:sm" />
-                               </pz:metadata>
-                               <pz:metadata type="title-uniform-parts">
-                                       <xsl:value-of select="tmarc:sn" />
-                               </pz:metadata>
-                               <pz:metadata type="title-uniform-partname">
-                                       <xsl:value-of select="tmarc:sp" />
-                               </pz:metadata>
-                               <pz:metadata type="title-uniform-key">
-                                       <xsl:value-of select="tmarc:sr" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d245">
-                               <pz:metadata type="title">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="title-remainder">
-                                       <xsl:value-of select="tmarc:sb" />
-                               </pz:metadata>
-                               <pz:metadata type="title-responsibility">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                               <pz:metadata type="title-dates">
-                                       <xsl:value-of select="tmarc:sf" />
-                               </pz:metadata>
-                               <pz:metadata type="title-medium">
-                                       <xsl:value-of select="tmarc:sh" />
-                               </pz:metadata>
-                               <pz:metadata type="title-number-section">
-                                       <xsl:value-of select="tmarc:sn" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d250">
-                               <pz:metadata type="edition">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d260">
-                               <pz:metadata type="publication-place">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="publication-name">
-                                       <xsl:value-of select="tmarc:sb" />
-                               </pz:metadata>
-                               <pz:metadata type="publication-date">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d300">
-                               <pz:metadata type="physical-extent">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="physical-format">
-                                       <xsl:value-of select="tmarc:sb" />
-                               </pz:metadata>
-                               <pz:metadata type="physical-dimensions">
-                                       <xsl:value-of select="tmarc:sc" />
-                               </pz:metadata>
-                               <pz:metadata type="physical-accomp">
-                                       <xsl:value-of select="tmarc:se" />
-                               </pz:metadata>
-                               <pz:metadata type="physical-unittype">
-                                       <xsl:value-of select="tmarc:sf" />
-                               </pz:metadata>
-                               <pz:metadata type="physical-unitsize">
-                                       <xsl:value-of select="tmarc:sg" />
-                               </pz:metadata>
-                               <pz:metadata type="physical-specified">
-                                       <xsl:value-of select="tmarc:s3" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d440">
-                               <pz:metadata type="series-title">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d500">
-                               <pz:metadata type="description">
-                                       <xsl:for-each select="node()">
-                                               <xsl:value-of select="text()" />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d505">
-                               <pz:metadata type="description">
-                                       <xsl:for-each select="node()">
-                                               <xsl:value-of select="text()" />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d518">
-                               <pz:metadata type="description">
-                                       <xsl:for-each select="node()">
-                                               <xsl:value-of select="text()" />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d520">
-                               <pz:metadata type="description">
-                                       <xsl:for-each select="node()">
-                                               <xsl:value-of select="text()" />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d522">
-                               <pz:metadata type="description">
-                                       <xsl:for-each select="node()">
-                                               <xsl:value-of select="text()" />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d600">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d610">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d611">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d630">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d648">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d650">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d651">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d653">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d654">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d655">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d656">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d657">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d658">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d662">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d69X">
-                               <pz:metadata type="subject">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                               <pz:metadata type="subject-long">
-                                       <xsl:for-each select="node()/text()">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text>, </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <!-- or tmarc:d651 or tmarc:d653 or tmarc:d654 or tmarc:d655 or tmarc:d656 
-                               or tmarc:d657 or tmarc:d658 or tmarc:d662 or tmarc:d69X"> -->
-
-                       <!-- <xsl:for-each select="tmarc:d600" > <pz:metadata type="subject"> 
-                               <xsl:value-of select="tmarc:sa"/> </pz:metadata> <pz:metadata type="subject-long"> 
-                               <xsl:for-each select="tmarc:sa tmarc:sb tmarc:sc tmarc:sd "> <xsl:if test="position() 
-                               > 1"> <xsl:text>, </xsl:text> </xsl:if> <xsl:value-of select="."/> </xsl:for-each> 
-                               </pz:metadata> </xsl:for-each> -->
-
-                       <xsl:for-each select="tmarc:d856">
-                               <pz:metadata type="electronic-url">
-                                       <xsl:value-of select="tmarc:su" />
-                               </pz:metadata>
-                               <pz:metadata type="electronic-text">
-                                       <xsl:if test="tmarc:sy">
-                                               <xsl:value-of select="tmarc:sy/text()" />
-                                       </xsl:if>
-                                       <xsl:if test="tmarc:s3">
-                                               <xsl:value-of select="tmarc:s3/text()" />
-                                       </xsl:if>
-                               </pz:metadata>
-                               <pz:metadata type="electronic-note">
-                                       <xsl:value-of select="tmarc:sz" />
-                               </pz:metadata>
-                               <pz:metadata type="electronic-format-instruction">
-                                       <xsl:value-of select="tmarc:si" />
-                               </pz:metadata>
-                               <pz:metadata type="electronic-format-type">
-                                       <xsl:value-of select="tmarc:sq" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d773">
-                               <pz:metadata type="citation">
-                                       <xsl:for-each select="*">
-                                               <xsl:value-of select="normalize-space(.)" />
-                                               <xsl:text> </xsl:text>
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d852">
-                               <xsl:if test="tmarc:sy">
-                                       <pz:metadata type="publicnote">
-                                               <xsl:value-of select="tmarc:sy" />
-                                       </pz:metadata>
-                               </xsl:if>
-                               <xsl:if test="tmarc:sh">
-                                       <pz:metadata type="callnumber">
-                                               <xsl:value-of select="tmarc:sh" />
-                                       </pz:metadata>
-                               </xsl:if>
-                       </xsl:for-each>
-
-                       <pz:metadata type="medium">
-                               <xsl:value-of select="$medium" />
-                       </pz:metadata>
-
-                       <xsl:for-each select="tmarc:d900/tmarc:sa">
-                               <pz:metadata type="fulltext">
-                                       <xsl:value-of select="." />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <!-- <xsl:if test="$fulltext_a"> <pz:metadata type="fulltext"> <xsl:value-of 
-                               select="$fulltext_a"/> </pz:metadata> </xsl:if> -->
-
-                       <xsl:for-each select="tmarc:d900/tmarc:sb">
-                               <pz:metadata type="fulltext">
-                                       <xsl:value-of select="." />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <!-- <xsl:if test="$fulltext_b"> <pz:metadata type="fulltext"> <xsl:value-of 
-                               select="$fulltext_b"/> </pz:metadata> </xsl:if> -->
-
-                       <xsl:for-each select="tmarc:d907">
-                               <!-- or tmarc:d901"> -->
-                               <pz:metadata type="iii-id">
-                                       <xsl:value-of select="tmarc:sa" />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d926">
-                               <pz:metadata type="holding">
-                                       <xsl:for-each select="tmarc:s">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text> </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d948">
-                               <pz:metadata type="holding">
-                                       <xsl:for-each select="tmarc:s">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text> </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <xsl:for-each select="tmarc:d991">
-                               <pz:metadata type="holding">
-                                       <xsl:for-each select="tmarc:s">
-                                               <xsl:if test="position() > 1">
-                                                       <xsl:text> </xsl:text>
-                                               </xsl:if>
-                                               <xsl:value-of select="." />
-                                       </xsl:for-each>
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <pz:metadata tag="tag100">
-                               <xsl:call-template name="shortTitle">
-                                       <xsl:with-param name="tag" select="100" />
-                               </xsl:call-template>
-                       </pz:metadata>
-
-                       <!-- Stuff for FRBR workset key -->
-                       <xsl:variable name="title130">
-                               <xsl:for-each select="tmarc:d130">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:value-of select="tmarc:sm" />
-                                       <xsl:value-of select="tmarc:sn" />
-                                       <xsl:value-of select="tmarc:sp" />
-                                       <xsl:value-of select="tmarc:sr" />
-                               </xsl:for-each>
-                       </xsl:variable>
-
-                       <xsl:variable name="title240">
-                               <xsl:for-each select="tmarc:d240">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:value-of select="tmarc:sm" />
-                                       <xsl:value-of select="tmarc:sn" />
-                                       <xsl:value-of select="tmarc:sp" />
-                                       <xsl:value-of select="tmarc:sr" />
-                               </xsl:for-each>
-                       </xsl:variable>
-                       <xsl:variable name="title242">
-                               <xsl:for-each select="tmarc:d242">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:if test="$contains110 and not($hasAuthorFields)">
-                                               <xsl:value-of select="tmarc:sb" />
-                                               <xsl:value-of select="tmarc:sf" />
-                                               <xsl:value-of select="tmarc:sg" />
-                                               <xsl:value-of select="tmarc:sn" />
-                                               <xsl:value-of select="tmarc:sp" />
-                                       </xsl:if>
-                               </xsl:for-each>
-                       </xsl:variable>
-                       <xsl:variable name="title242-full">
-                               <xsl:for-each select="tmarc:d242">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:value-of select="tmarc:sb" />
-                                       <xsl:value-of select="tmarc:sf" />
-                                       <xsl:value-of select="tmarc:sg" />
-                                       <xsl:value-of select="tmarc:sn" />
-                                       <xsl:value-of select="tmarc:sp" />
-                               </xsl:for-each>
-                       </xsl:variable>
-
-                       <xsl:variable name="title245">
-                               <xsl:for-each select="tmarc:d245">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:if test="$contains110 and not($hasAuthorFields)">
-                                               <xsl:value-of select="tmarc:sb" />
-                                               <xsl:value-of select="tmarc:sf" />
-                                               <xsl:value-of select="tmarc:sg" />
-                                               <xsl:value-of select="tmarc:sn" />
-                                               <xsl:value-of select="tmarc:sp" />
-                                       </xsl:if>
-                               </xsl:for-each>
-                       </xsl:variable>
-                       <xsl:variable name="title245-full">
-                               <xsl:for-each select="tmarc:d245">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:value-of select="tmarc:sb" />
-                                       <xsl:value-of select="tmarc:sf" />
-                                       <xsl:value-of select="tmarc:sg" />
-                                       <xsl:value-of select="tmarc:sn" />
-                                       <xsl:value-of select="tmarc:sp" />
-                               </xsl:for-each>
-                       </xsl:variable>
-
-                       <xsl:variable name="title246">
-                               <xsl:for-each select="tmarc:d246">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:if test="$contains110 and not($hasAuthorFields)">
-                                               <xsl:value-of select="tmarc:sb" />
-                                               <xsl:value-of select="tmarc:sf" />
-                                               <xsl:value-of select="tmarc:sg" />
-                                               <xsl:value-of select="tmarc:sn" />
-                                               <xsl:value-of select="tmarc:sp" />
-                                       </xsl:if>
-                               </xsl:for-each>
-                       </xsl:variable>
-                       <xsl:variable name="title246-full">
-                               <xsl:for-each select="tmarc:d246">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:value-of select="tmarc:sb" />
-                                       <xsl:value-of select="tmarc:sf" />
-                                       <xsl:value-of select="tmarc:sg" />
-                                       <xsl:value-of select="tmarc:sn" />
-                                       <xsl:value-of select="tmarc:sp" />
-                               </xsl:for-each>
-                       </xsl:variable>
-
-                       <xsl:variable name="title247">
-                               <xsl:for-each select="tmarc:d247">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:if test="$contains110 and not($hasAuthorFields)">
-                                               <xsl:value-of select="tmarc:sb" />
-                                               <xsl:value-of select="tmarc:sf" />
-                                               <xsl:value-of select="tmarc:sg" />
-                                               <xsl:value-of select="tmarc:sn" />
-                                               <xsl:value-of select="tmarc:sp" />
-                                       </xsl:if>
-                               </xsl:for-each>
-                       </xsl:variable>
-                       <xsl:variable name="title247-full">
-                               <xsl:for-each select="tmarc:d247">
-                                       <xsl:value-of select="tmarc:sa" />
-                                       <xsl:value-of select="tmarc:sb" />
-                                       <xsl:value-of select="tmarc:sf" />
-                                       <xsl:value-of select="tmarc:sg" />
-                                       <xsl:value-of select="tmarc:sn" />
-                                       <xsl:value-of select="tmarc:sp" />
-                               </xsl:for-each>
-                       </xsl:variable>
-
-                       <xsl:for-each select="tmarc:c008">
-                               <pz:metadata type="meta-marc-cf008">
-                                       <xsl:value-of select="." />
-                               </pz:metadata>
-                       </xsl:for-each>
-
-                       <pz:metadata type="meta-frbr-short-title">
-                               <xsl:choose>
-                                       <xsl:when test="$title130!=''">
-                                               <xsl:value-of select="$title130" />
-                                       </xsl:when>
-                                       <xsl:when test="$title130='' and $title240!=''">
-                                               <xsl:value-of select="$title240" />
-                                       </xsl:when>
-                                       <!-- Missing the prioritization of 246 on non-english records -->
-                                       <xsl:when test="$title130='' and $title240='' and $title242!=''">
-                                               <xsl:value-of select="$title242" />
-                                       </xsl:when>
-                                       <xsl:when
-                                               test="$title130='' and $title240='' and $title242='' and $title245!=''">
-                                               <xsl:value-of select="$title245" />
-                                       </xsl:when>
-                                       <xsl:when
-                                               test="$title130='' and $title240='' and $title242='' and $title246!=''">
-                                               <xsl:value-of select="$title246" />
-                                       </xsl:when>
-                                       <xsl:when
-                                               test="$title130='' and $title240='' and $title242='' and $title246='' and $title247!=''">
-                                               <xsl:value-of select="$title247" />
-                                       </xsl:when>
-                               </xsl:choose>
-                       </pz:metadata>
-
-                       <pz:metadata type="meta-frbr-full-title">
-                               <xsl:choose>
-                                       <xsl:when test="$title130!=''">
-                                               <xsl:value-of select="$title130" />
-                                       </xsl:when>
-                                       <xsl:when test="$title130='' and $title240!=''">
-                                               <xsl:value-of select="$title240" />
-                                       </xsl:when>
-                                       <!-- Missing the prioritization of 246 on non-english records -->
-                                       <xsl:when test="$title130='' and $title240='' and $title242!=''">
-                                               <xsl:value-of select="$title242-full" />
-                                       </xsl:when>
-                                       <xsl:when
-                                               test="$title130='' and $title240='' and $title242='' and $title245!=''">
-                                               <xsl:value-of select="$title245-full" />
-                                       </xsl:when>
-                                       <xsl:when
-                                               test="$title130='' and $title240='' and $title242='' and $title246!=''">
-                                               <xsl:value-of select="$title246-full" />
-                                       </xsl:when>
-                                       <xsl:when
-                                               test="$title130='' and $title240='' and $title242='' and $title246='' and $title247!=''">
-                                               <xsl:value-of select="$title247-full" />
-                                       </xsl:when>
-                               </xsl:choose>
-                       </pz:metadata>
-
-
-                       <pz:metadata type="meta-frbr-lang">
-                               <xsl:value-of select="$control_lang" />
-                       </pz:metadata>
-
-
-                       <!-- passthrough id data -->
-                       <xsl:for-each select="pz:metadata">
-                               <xsl:copy-of select="." />
-                       </xsl:for-each>
-
-                       <!-- other stylesheets importing this might want to define this -->
-                       <xsl:call-template name="record-hook" />
-
-               </pz:record>
-       </xsl:template>
-
-       <xsl:template match="text()" />
-
-       <!-- TODO Does not work anymore -->
-       <xsl:template name="shortTitle">
-               <xsl:param name="tag" />
-               <xsl:for-each select="tmarc:d">
-                       <xsl:value-of select="tmarc:sa" />
-                       <xsl:value-of select="tmarc:sm" />
-                       <xsl:value-of select="tmarc:sn" />
-                       <xsl:value-of select="tmarc:sp" />
-                       <xsl:value-of select="tmarc:sr" />
-               </xsl:for-each>
-       </xsl:template>
-
-       <!-- No working as expected -->
-       <xsl:template name="description">
-               <xsl:param name="element" />
-               <xsl:for-each select="$element">
-                       <pz:metadata type="description">
-                               <xsl:for-each select="node()">
-                                       <xsl:value-of select="text()" />
-                               </xsl:for-each>
-                       </pz:metadata>
-               </xsl:for-each>
-               <xsl:apply-templates />
-       </xsl:template>
-
-       <!-- <xsl:for-each select="tmarc:d500"> <pz:metadata type="description"> 
-               <xsl:for-each select="node()"> <xsl:value-of select="text()"/> </xsl:for-each> 
-               </pz:metadata> </xsl:for-each> -->
-
-
-
-       <xsl:template name="subject">
-               <xsl:param name="element" />
-               <xsl:for-each select="$element">
-                       <pz:metadata type="subject">
-                               <xsl:value-of select="tmarc:sa" />
-                       </pz:metadata>
-                       <pz:metadata type="subject-long">
-                               <xsl:for-each select="node()/text()">
-                                       <xsl:if test="position() > 1">
-                                               <xsl:text>, </xsl:text>
-                                       </xsl:if>
-                                       <xsl:value-of select="." />
-                               </xsl:for-each>
-                       </pz:metadata>
-               </xsl:for-each>
-       </xsl:template>
-
-
-</xsl:stylesheet>
index 0da406c..c5413bf 100644 (file)
@@ -1,2 +1,4 @@
 *.log
 *.xml
+*.time
+run*
index b01a265..0374b46 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/bash
 DELAY=0.001
 WAIT=5
-NUMBER=40
+NUMBER=10
 ROUNDS=5
 if test -n "$1"; then
        . $1
index f9f0dc2..6b8f52f 100644 (file)
@@ -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 <yaz/log.h>
 #include <yaz/comstack.h>
 #include <yaz/xmalloc.h>
+#include <yaz/mutex.h>
+#include <yaz/poll.h>
 #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
index 9b1825d..b37eca9 100644 (file)
@@ -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 "<settings><status>OK</status></settings>";
     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, "</termlist>\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, "</bytarget>");
     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, "</show>\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 "<ping><status>OK</status></ping>";
     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 "<search><status>OK</status></search>";
     http_send_response(c);
+    release_session(c,s);
 }
 
 
@@ -1033,6 +1054,7 @@ static void cmd_stat(struct http_channel *c)
     wrbuf_puts(c->wrbuf, "</stat>");
     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)
index 10b6d16..0677761 100644 (file)
@@ -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);
 }
index 14b9a2c..b17b29b 100644 (file)
@@ -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;