dnl This file is part of the YAZ toolkit.
dnl Copyright (C) 1995-2010 Index Data
AC_PREREQ([2.60])
-AC_INIT([yaz],[4.0.8],[yaz-help@indexdata.dk])
+AC_INIT([yaz],[4.0.9],[yaz-help@indexdata.dk])
AC_CONFIG_SRCDIR([configure.ac])
AC_CONFIG_AUX_DIR([config])
AM_INIT_AUTOMAKE([1.9])
+yaz (4.0.9-1indexdata) unstable; urgency=low
+
+ * New yaz_thread functions
+
+ -- Adam Dickmeiss <adam@indexdata.dk> Wed, 19 May 2010 15:19:25 +0200
+
yaz (4.0.8-2indexdata) unstable; urgency=low
* Remove *.la files
This package includes HTML documentation for YAZ.
Package: libyaz4-dev
-Depends: libyaz4 (= ${Source-Version}), libxslt1-dev, libicu36-dev|libicu-dev, libgnutls-dev, tcl8.3|tclsh
+Depends: libyaz4 (= ${Source-Version}), libxslt1-dev, libicu36-dev|libicu-dev, tcl8.3|tclsh
Replaces: yaz-devel
Conflicts: yaz-devel, libyaz-dev, libyaz2-dev, libyaz3-dev
Section: libdevel
-Subproject commit cc80f24dcf550d033c2fdf29ea35b4e0961f357d
+Subproject commit ca4e4fa028634b4e07f011eb6375e205ae96c709
<term><literal>HAVE_TCL</literal>, <literal>TCL</literal></term>
<listitem><para>
If <literal>HAVE_TCL</literal> is set to 1, nmake will
- use the ASN.1 compiler (Tcl based). You must set
- <literal>TCL</literal> to the full path of the Tcl
+ use the ASN.1 compiler (<ulink url="&url.tcl;">Tcl</ulink> based).
+ You must set <literal>TCL</literal> to the full path of the Tcl
interpreter.
</para>
<para>
z-univ.h z-oclcui.h zes-expi.h zes-exps.h zes-order.h zes-pquery.h \
zes-psched.h zes-admin.h zes-pset.h zes-update.h zes-update0.h \
zoom.h z-charneg.h charneg.h soap.h srw.h zgdu.h matchstr.h json.h \
- file_glob.h dirent.h thread_id.h gettimeofday.h shptr.h
+ file_glob.h dirent.h thread_id.h gettimeofday.h shptr.h thread_create.h \
+ spipe.h
EXTRA_DIST = yaz-version.h.in
typedef struct DIR DIR;
-DIR *opendir (const char *path);
-struct dirent *readdir (DIR *dd);
-void closedir (DIR *dd);
+YAZ_EXPORT DIR *opendir (const char *path);
+YAZ_EXPORT struct dirent *readdir (DIR *dd);
+YAZ_EXPORT void closedir (DIR *dd);
YAZ_END_CDECL
* (any number of any char)
* (zero or more)
*/
+YAZ_EXPORT
int yaz_match_glob(const char *glob, const char *text);
YAZ_END_CDECL
--- /dev/null
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Index Data nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file spipe.h
+ * \brief socket-pipe header
+ */
+#ifndef YAZ_SPIPE_H
+#define YAZ_SPIPE_H
+
+#include <stddef.h>
+#include <time.h>
+#include <yaz/yconfig.h>
+#include <yaz/wrbuf.h>
+
+YAZ_BEGIN_CDECL
+
+/** \brief YAZ socket pipe opaque pointer */
+typedef struct yaz_spipe *yaz_spipe_t;
+
+/** \brief create socket pipe
+ \param port_to_use port that we temporarily bind to
+ \param err_msg error message reference (0 if not to be set)
+ \returns 0 on failure; != 0 on success
+ */
+YAZ_EXPORT yaz_spipe_t yaz_spipe_create(int port_to_use, WRBUF *err_msg);
+
+/** \brief destroys socket pipe
+ \param p socket pipe pointer
+ */
+YAZ_EXPORT void yaz_spipe_destroy(yaz_spipe_t p);
+
+/** \brief returns reading socket
+ \param p socket pipe pointer
+ */
+YAZ_EXPORT int yaz_spipe_get_read_fd(yaz_spipe_t p);
+
+/** \brief returns writing socket
+ \param p socket pipe pointer
+ */
+YAZ_EXPORT int yaz_spipe_get_write_fd(yaz_spipe_t p);
+
+YAZ_END_CDECL
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
--- /dev/null
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data.
+ * All rights reserved.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Index Data nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file thread_create.h
+ * \brief Implements thread creation wrappers
+ */
+#ifndef YAZ_THREAD_CREATE_H
+#define YAZ_THREAD_CREATE_H
+
+#include <stddef.h>
+#include <time.h>
+#include <yaz/yconfig.h>
+
+YAZ_BEGIN_CDECL
+
+/** \brief Thread Identifier opaque pointer */
+typedef struct yaz_thread *yaz_thread_t;
+
+/** \brief create thread
+ \param start_routine thread handler
+ \param arg user data to be passed to handler
+ \returns thread_id identifier if successful; NULL on failure
+ */
+YAZ_EXPORT yaz_thread_t yaz_thread_create(void *(*start_routine)(void *p), void *arg);
+
+/** \brief join thread
+ \param tp thread_id reference .. Will be 0 upon completion
+ \param value_ptr ref pointer to routine result (0 if not needed)
+*/
+YAZ_EXPORT void yaz_thread_join(yaz_thread_t *tp, void **value_ptr);
+
+/** \brief detach thread
+ \param tp thread_id reference .. Will be 0 upon completion
+*/
+void yaz_thread_detach(yaz_thread_t *tp);
+
+YAZ_END_CDECL
+
+#endif
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
iconv_encode_marc8.c iconv_encode_iso_8859_1.c iconv_encode_wchar.c \
iconv_decode_marc8.c iconv_decode_iso5426.c iconv_decode_danmarc.c sc.c \
json.c xml_include.c file_glob.c dirent.c mutex-p.h mutex.c condvar.c \
- thread_id.c gettimeofday.c
+ thread_id.c gettimeofday.c thread_create.c spipe.c
libyaz_la_LDFLAGS=-version-info $(YAZ_VERSION_INFO)
void yaz_cond_create(YAZ_COND *p)
{
- *p = (YAZ_COND) malloc(sizeof(**p));
#ifdef WIN32
+ *p = (YAZ_COND) malloc(sizeof(**p));
InitializeConditionVariable(&(*p)->cond);
#elif YAZ_POSIX_THREADS
+ *p = (YAZ_COND) malloc(sizeof(**p));
pthread_cond_init(&(*p)->cond, 0);
+#else
+ *p = 0;
#endif
}
int yaz_cond_wait(YAZ_COND p, YAZ_MUTEX m, const struct timeval *abstime)
{
#ifdef WIN32
+ BOOL v;
if (abstime)
{
struct timeval tval_now;
sec = abstime->tv_sec - tval_now.tv_sec;
msec = (abstime->tv_usec - tval_now.tv_usec) / 1000;
- return SleepConditionVariableCS(&p->cond, &m->handle, sec*1000 + msec);
+ v = SleepConditionVariableCS(&p->cond, &m->handle, sec*1000 + msec);
}
else
- return SleepConditionVariableCS(&p->cond, &m->handle, INFINITE);
+ v = SleepConditionVariableCS(&p->cond, &m->handle, INFINITE);
+ return v ? 0 : -1;
#elif YAZ_POSIX_THREADS
if (abstime)
{
--- /dev/null
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data
+ * See the file LICENSE for details.
+ */
+
+/**
+ * \file spipe.c
+ * \brief Implements socket-pipes
+ *
+ */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <yaz/xmalloc.h>
+#include <yaz/nmem.h>
+#include <yaz/log.h>
+#include <yaz/spipe.h>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef WIN32
+#include <winsock2.h>
+#define YAZ_INVALID_SOCKET INVALID_SOCKET
+#else
+#define YAZ_INVALID_SOCKET -1
+#include <fcntl.h>
+#endif
+
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+#if HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#if HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#if HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#if HAVE_NETINET_TCP_H
+#include <netinet/tcp.h>
+#endif
+
+struct yaz_spipe {
+ int m_fd[2];
+ int m_socket;
+};
+
+static void yaz_spipe_close(int *fd)
+{
+#ifdef WIN32
+ if (*fd != YAZ_INVALID_SOCKET)
+ closesocket(*fd);
+#else
+ if (*fd != YAZ_INVALID_SOCKET)
+ close(*fd);
+#endif
+ *fd = YAZ_INVALID_SOCKET;
+}
+
+static int nonblock(int s)
+{
+#ifdef WIN32
+ unsigned long tru = 1;
+ if (ioctlsocket(s, FIONBIO, &tru))
+ return -1;
+#else
+ if (fcntl(s, F_SETFL, O_NONBLOCK))
+ return -1;
+#endif
+ return 0;
+}
+
+yaz_spipe_t yaz_spipe_create(int port_to_use, WRBUF *err_msg)
+{
+ yaz_spipe_t p = xmalloc(sizeof(*p));
+
+#ifdef WIN32
+ {
+ WSADATA wsaData;
+ WORD wVersionRequested = MAKEWORD(2, 0);
+ if (WSAStartup( wVersionRequested, &wsaData))
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "WSAStartup failed");
+ xfree(p);
+ return 0;
+ }
+ }
+#endif
+ p->m_fd[0] = p->m_fd[1] = YAZ_INVALID_SOCKET;
+ p->m_socket = YAZ_INVALID_SOCKET;
+
+ if (port_to_use)
+ {
+ struct sockaddr_in add;
+ struct sockaddr *addr = 0;
+ unsigned int tmpadd;
+ struct sockaddr caddr;
+#ifdef WIN32
+ int caddr_len = sizeof(caddr);
+#else
+ socklen_t caddr_len = sizeof(caddr);
+#endif
+ fd_set write_set;
+
+ // create server socket
+ p->m_socket = socket(AF_INET, SOCK_STREAM, 0);
+ if (p->m_socket == YAZ_INVALID_SOCKET)
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "socket call failed");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+#ifndef WIN32
+ {
+ unsigned long one = 1;
+ if (setsockopt(p->m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)
+ &one, sizeof(one)))
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "setsockopt call failed");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+ }
+#endif
+ // bind server socket
+ add.sin_family = AF_INET;
+ add.sin_port = htons(port_to_use);
+ add.sin_addr.s_addr = INADDR_ANY;
+ addr = ( struct sockaddr *) &add;
+
+ if (bind(p->m_socket, addr, sizeof(struct sockaddr_in)))
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "could not bind to socket");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+
+ if (listen(p->m_socket, 3) < 0)
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "could not listen on socket");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+
+ // client socket
+ tmpadd = (unsigned) inet_addr("127.0.0.1");
+ if (!tmpadd)
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "inet_addr failed");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+
+ memcpy(&add.sin_addr.s_addr, &tmpadd, sizeof(struct in_addr));
+ p->m_fd[1] = socket(AF_INET, SOCK_STREAM, 0);
+ if (p->m_fd[1] == YAZ_INVALID_SOCKET)
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "socket call failed (2)");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+ nonblock(p->m_fd[1]);
+
+ if (connect(p->m_fd[1], addr, sizeof(*addr)))
+ {
+ if (
+#ifdef WIN32
+ WSAGetLastError() != WSAEWOULDBLOCK
+#else
+ errno != EINPROGRESS
+#endif
+ )
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "connect call failed");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+ }
+
+ /* server accept */
+ p->m_fd[0] = accept(p->m_socket, &caddr, &caddr_len);
+ if (p->m_fd[0] == YAZ_INVALID_SOCKET)
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "accept failed");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+
+ /* complete connect */
+ FD_ZERO(&write_set);
+ FD_SET(p->m_fd[1], &write_set);
+ if (select(p->m_fd[1]+1, 0, &write_set, 0, 0) != 1)
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "could not complete connect");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+ yaz_spipe_close(&p->m_socket);
+ }
+ else
+ {
+#ifdef WIN32
+ yaz_spipe_destroy(p);
+ return 0;
+#else
+ if (pipe(p->m_fd))
+ {
+ if (err_msg)
+ wrbuf_printf(*err_msg, "pipe call failed");
+ yaz_spipe_destroy(p);
+ return 0;
+ }
+ assert(p->m_fd[0] != YAZ_INVALID_SOCKET);
+ assert(p->m_fd[1] != YAZ_INVALID_SOCKET);
+#endif
+ }
+
+ return p;
+}
+
+void yaz_spipe_destroy(yaz_spipe_t p)
+{
+ yaz_spipe_close(&p->m_fd[0]);
+ yaz_spipe_close(&p->m_fd[1]);
+ yaz_spipe_close(&p->m_socket);
+ xfree(p);
+#ifdef WIN32
+ WSACleanup();
+#endif
+}
+
+int yaz_spipe_get_read_fd(yaz_spipe_t p)
+{
+ return p->m_fd[0];
+}
+
+int yaz_spipe_get_write_fd(yaz_spipe_t p)
+{
+ return p->m_fd[1];
+}
+
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
--- /dev/null
+/* This file is part of the YAZ toolkit.
+ * Copyright (C) 1995-2010 Index Data
+ * See the file LICENSE for details.
+ */
+
+/**
+ * \file thread_create.c
+ * \brief Implements thread creation wrappers
+ *
+ */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stddef.h>
+#include <yaz/xmalloc.h>
+#include <yaz/log.h>
+#include <yaz/thread_create.h>
+
+#if YAZ_POSIX_THREADS
+#include <pthread.h>
+#endif
+#ifdef WIN32
+#include <windows.h>
+#include <process.h>
+#endif
+
+struct yaz_thread {
+#if YAZ_POSIX_THREADS
+ pthread_t id;
+#else
+#ifdef WIN32
+ HANDLE handle;
+ void *(*routine)(void *p);
+#endif
+ void *data;
+#endif
+};
+
+#ifdef WIN32
+unsigned int __stdcall win32_routine(void *p)
+{
+ yaz_thread_t t = (yaz_thread_t) p;
+ void *userdata = t->data;
+ t->data = t->routine(userdata);
+ _endthreadex(0);
+ return 0;
+}
+#endif
+
+yaz_thread_t yaz_thread_create(void *(*start_routine)(void *p), void *arg)
+{
+ yaz_thread_t t = xmalloc(sizeof(*t));
+#if YAZ_POSIX_THREADS
+ int r = pthread_create(&t->id, 0, start_routine, arg);
+ if (r)
+ {
+ xfree(t);
+ t = 0;
+ }
+#else
+#ifdef WIN32
+ /* we create a wrapper on windows and pass yaz_thread struct to that */
+ unsigned threadID;
+ uintptr_t ex_ret;
+ t->data = arg; /* use data for both input and output */
+ t->routine = start_routine;
+ ex_ret = _beginthreadex(NULL, 0, win32_routine, t, 0, &threadID);
+ if (ex_ret == -1L)
+ {
+ xfree(t);
+ t = 0;
+ }
+ t->handle = (HANDLE) ex_ret;
+#else
+ t->data = start_routine(arg);
+#endif
+#endif
+ return t;
+}
+
+void yaz_thread_join(yaz_thread_t *tp, void **value_ptr)
+{
+ if (*tp)
+ {
+#ifdef YAZ_POSIX_THREADS
+ pthread_join((*tp)->id, value_ptr);
+#else
+#ifdef WIN32
+ WaitForSingleObject((*tp)->handle, INFINITE);
+ CloseHandle((*tp)->handle);
+#endif
+ if (value_ptr)
+ *value_ptr = (*tp)->data;
+#endif
+ xfree(*tp);
+ *tp = 0;
+ }
+}
+
+void yaz_thread_detach(yaz_thread_t *tp)
+{
+ if (*tp)
+ {
+#ifdef YAZ_POSIX_THREADS
+ pthread_detach((*tp)->id);
+#else
+#ifdef WIN32
+ CloseHandle((*tp)->handle);
+#endif
+#endif
+ xfree(*tp);
+ *tp = 0;
+ }
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * c-file-style: "Stroustrup"
+ * indent-tabs-mode: nil
+ * End:
+ * vim: shiftwidth=4 tabstop=8 expandtab
+ */
+
#include <stdio.h>
#include <yaz/mutex.h>
+#include <yaz/thread_create.h>
#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
return;
yaz_cond_create(&c);
- YAZ_CHECK(c);
- if (!c)
- return;
-
- r = yaz_gettimeofday(&abstime);
- YAZ_CHECK_EQ(r, 0);
-
- abstime.tv_sec += 1; /* wait 1 second */
-
- r = yaz_cond_wait(c, p, &abstime);
- YAZ_CHECK(r != 0);
+ if (c)
+ {
+ r = yaz_gettimeofday(&abstime);
+ YAZ_CHECK_EQ(r, 0);
+
+ abstime.tv_sec += 1; /* wait 1 second */
+
+ r = yaz_cond_wait(c, p, &abstime);
+ YAZ_CHECK(r != 0);
+ }
yaz_cond_destroy(&c);
YAZ_CHECK(c == 0);
yaz_mutex_destroy(&p);
YAZ_CHECK(p == 0);
}
+static void *my_handler(void *arg)
+{
+ int *mydata = (int*) arg;
+ (*mydata)++;
+ return mydata;
+}
+
+static void tst_create_thread(void)
+{
+ void *return_data;
+ int mydata = 42;
+ yaz_thread_t t[2];
+
+ t[0] = yaz_thread_create(my_handler, &mydata);
+ YAZ_CHECK(t[0]);
+ t[1] = yaz_thread_create(my_handler, &mydata);
+ YAZ_CHECK(t[1]);
+
+ return_data = 0;
+ yaz_thread_join(&t[0], &return_data);
+ YAZ_CHECK(!t[0]);
+ YAZ_CHECK(return_data == &mydata);
+
+ return_data = 0;
+ yaz_thread_join(&t[1], &return_data);
+ YAZ_CHECK(!t[1]);
+ YAZ_CHECK(return_data == &mydata);
+
+ YAZ_CHECK_EQ(mydata, 44);
+}
+
int main (int argc, char **argv)
{
YAZ_CHECK_INIT(argc, argv);
YAZ_CHECK_LOG();
tst_mutex();
tst_cond();
+ tst_create_thread();
YAZ_CHECK_TERM;
}
LINK_LIBS= kernel32.lib ws2_32.lib advapi32.lib \
$(ICONV_LIB) $(LIBXML2_LIB) $(LIBXSLT_LIB)
-COMMON_LNK_OPTIONS= /nologo /subsystem:windows /machine:i386 /incremental:no
+COMMON_LNK_OPTIONS= /nologo /subsystem:windows /incremental:no
DEBUG_LNK_OPTIONS= /debug
$(OBJDIR)\iconv_decode_iso5426.obj \
$(OBJDIR)\iconv_decode_danmarc.obj \
$(OBJDIR)\mutex.obj \
+ $(OBJDIR)\thread_create.obj \
+ $(OBJDIR)\spipe.obj \
$(OBJDIR)\gettimeofday.obj \
$(OBJDIR)\json.obj \
$(OBJDIR)\sc.obj \
%package -n libyaz4-devel
Summary: Z39.50 Library - development package
Group: Development/Libraries
-Requires: libyaz4 = %{version} libxml2-devel libxslt-devel libicu-devel gnutls-devel %{TCPWRAPPER}
+Requires: libyaz4 = %{version} libxml2-devel libxslt-devel libicu-devel
Conflicts: libyaz-devel
%description -n libyaz4-devel
rm -fr ${RPM_BUILD_ROOT}
make prefix=${RPM_BUILD_ROOT}/%{_prefix} mandir=${RPM_BUILD_ROOT}/%{_mandir} \
libdir=${RPM_BUILD_ROOT}/%{_libdir} install
+rm ${RPM_BUILD_ROOT}/%{_libdir}/*.la
%clean
rm -fr ${RPM_BUILD_ROOT}