Possible compatibility problems with earlier versions marked with '*'.
+Added sort facility in client and backend server interface.
+
Fixed problem with dependencies in Makefile(s).
Fixed bugs for encoders/decoders of extended services and
function statserv_main uses the NT service when required and
calls the statserv_start / statserv_close routines.
-Routine zget_SearchRequest fills resultSetName member with "default"
-instead of "Default".
+Routine zget_SearchRequest and zget_PresentRequest fills
+resultSetName/Id member with "default" instead of "Default".
Fixed memory leak in server. Request queue member wasn't freed.
* Sebastian Hammer, Adam Dickmeiss
Compilation and installation for YAZ
- $Id: README,v 1.19 1998-01-07 12:59:27 adam Exp $
+ $Id: README,v 1.20 1998-01-29 13:30:23 adam Exp $
The primary output of the source here is the lib/libyaz.a library,
which contains support functions for implementing the server or client
We maintain a mailing-list for the purpose of announcing new versions of
the software, bug-reports, discussion etc. You can sign up by sending
-mail to yaz-request@indexdata.dk.
+mail to yaz-request@indexdata.dk and include the following command
+command in your email:
+ subscribe yaz-l
+
/*
- * Copyright (c) 1995-1997, Index Data
+ * Copyright (c) 1995-1998, Index Data
* See the file LICENSE for details.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: eventl.c,v $
- * Revision 1.24 1997-09-04 14:19:13 adam
+ * Revision 1.25 1998-01-29 13:30:23 adam
+ * Better event handle system for NT/Unix.
+ *
+ * Revision 1.24 1997/09/04 14:19:13 adam
* Added credits.
*
* Revision 1.23 1997/09/01 08:52:59 adam
#include <errno.h>
#include <string.h>
+#include <log.h>
+#include <comstack.h>
+#include <xmalloc.h>
#include "eventl.h"
-#include "log.h"
-#include "comstack.h"
#include "session.h"
-#include "statserv.h"
-#include <xmalloc.h>
-
-#ifndef WINDOWS
-
-static IOCHAN iochans = 0;
-
-IOCHAN iochan_getchan(void)
-{
- return iochans;
-}
-
-#endif /* WINDOWS */
+#include <statserv.h>
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags)
{
new_iochan->fun = cb;
new_iochan->force_event = 0;
new_iochan->last_event = new_iochan->max_idle = 0;
-
-#ifdef WINDOWS
- /* For windows we don't have a linklist of iochans */
new_iochan->next = NULL;
-#else /* WINDOWS */
- new_iochan->next = iochans;
- iochans = new_iochan;
-#endif /* WINDOWS */
-
return new_iochan;
}
-/* Event loop now takes an iochan as a parameter */
-#ifdef WINDOWS
-int __stdcall event_loop(IOCHAN iochans)
-#else
-int event_loop(IOCHAN dummylistener)
-#endif
+int event_loop(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 nullto = {0, 0}, to;
- struct timeval *timeout;
-
- FD_ZERO(&in);
- FD_ZERO(&out);
- FD_ZERO(&except);
- timeout = &to; /* hang on select */
- to.tv_sec = 5*60;
- to.tv_usec = 0;
- max = 0;
- for (p = iochans; p; p = p->next)
+ fd_set in, out, except;
+ int res, max;
+ static struct timeval nullto = {0, 0}, to;
+ struct timeval *timeout;
+
+ FD_ZERO(&in);
+ FD_ZERO(&out);
+ FD_ZERO(&except);
+ timeout = &to; /* hang on select */
+ to.tv_sec = 5*60;
+ to.tv_usec = 0;
+ max = 0;
+ for (p = *iochans; p; p = p->next)
{
- if (p->force_event)
- timeout = &nullto; /* polling select */
- 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 ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
- {
- if (errno == EINTR)
- continue;
+ if (p->force_event)
+ timeout = &nullto; /* polling select */
+ 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 ((res = select(max + 1, &in, &out, &except, timeout)) < 0)
+ {
+ if (errno == EINTR)
+ continue;
else
{
/* Destroy the first member in the chain, and try again */
- association *assoc = iochan_getdata(iochans);
+ association *assoc = iochan_getdata(*iochans);
COMSTACK conn = assoc->client_link;
cs_close(conn);
- destroy_association(assoc);
- iochan_destroy(iochans);
- logf(LOG_DEBUG, "error while selecting, destroying iochan %p", iochans);
+ destroy_association(assoc);
+ iochan_destroy(*iochans);
+ logf(LOG_DEBUG, "error while selecting, destroying iochan %p",
+ *iochans);
}
- }
- for (p = iochans; p; p = p->next)
+ }
+ for (p = *iochans; p; p = p->next)
{
- int force_event = p->force_event;
- time_t now = time(0);
+ int force_event = p->force_event;
+ time_t now = time(0);
- p->force_event = 0;
- if (!p->destroyed && (FD_ISSET(p->fd, &in) || force_event == EVENT_INPUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_INPUT);
- }
- if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
- force_event == EVENT_OUTPUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_OUTPUT);
- }
- if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
- force_event == EVENT_EXCEPT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_EXCEPT);
- }
- if (!p->destroyed && ((p->max_idle && now - p->last_event >
- p->max_idle) || force_event == EVENT_TIMEOUT))
- {
- p->last_event = now;
- (*p->fun)(p, EVENT_TIMEOUT);
- }
+ p->force_event = 0;
+ if (!p->destroyed && (FD_ISSET(p->fd, &in) ||
+ force_event == EVENT_INPUT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_INPUT);
}
- for (p = iochans; p; p = nextp)
+ if (!p->destroyed && (FD_ISSET(p->fd, &out) ||
+ force_event == EVENT_OUTPUT))
{
- nextp = p->next;
+ p->last_event = now;
+ (*p->fun)(p, EVENT_OUTPUT);
+ }
+ if (!p->destroyed && (FD_ISSET(p->fd, &except) ||
+ force_event == EVENT_EXCEPT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_EXCEPT);
+ }
+ if (!p->destroyed && ((p->max_idle && now - p->last_event >
+ p->max_idle) || force_event == EVENT_TIMEOUT))
+ {
+ p->last_event = now;
+ (*p->fun)(p, EVENT_TIMEOUT);
+ }
+ }
+ for (p = *iochans; p; p = nextp)
+ {
+ nextp = p->next;
- if (p->destroyed)
- {
- IOCHAN tmp = p, pr;
+ if (p->destroyed)
+ {
+ IOCHAN tmp = p, pr;
/* We need to inform the threadlist that this channel has been destroyed */
statserv_remove(p);
- /* Now reset the pointers */
- if (p == iochans)
- iochans = p->next;
- else
- {
- for (pr = iochans; pr; pr = pr->next)
- if (pr->next == p)
- break;
- assert(pr); /* grave error if it weren't there */
- pr->next = p->next;
- }
- if (nextp == p)
- nextp = p->next;
- xfree(tmp);
- }
+ /* Now reset the pointers */
+ if (p == *iochans)
+ *iochans = p->next;
+ else
+ {
+ for (pr = *iochans; pr; pr = pr->next)
+ if (pr->next == p)
+ break;
+ assert(pr); /* grave error if it weren't there */
+ pr->next = p->next;
+ }
+ if (nextp == p)
+ nextp = p->next;
+ xfree(tmp);
}
+ }
}
- while (iochans);
+ while (*iochans);
return 0;
}
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: eventl.h,v $
- * Revision 1.9 1997-09-01 09:31:48 adam
+ * Revision 1.10 1998-01-29 13:30:23 adam
+ * Better event handle system for NT/Unix.
+ *
+ * Revision 1.9 1997/09/01 09:31:48 adam
* Removed definition statserv_remove from statserv.h to eventl.h.
*
* Revision 1.8 1995/06/19 12:39:09 quinn
#define iochan_getnext(i) ((i)->next)
#define iochan_settimeout(i, t) ((i)->max_idle = (t), (i)->last_event = time(0))
-IOCHAN iochan_getchan(void);
IOCHAN iochan_create(int fd, IOC_CALLBACK cb, int flags);
-#ifdef WINDOWS
-int __stdcall event_loop(IOCHAN iochans);
-#else
-int event_loop(IOCHAN dummylistener);
-#endif
-
+int event_loop(IOCHAN *iochans);
void statserv_remove (IOCHAN pIOChannel);
#endif
/*
- * Copyright (C) 1995, Index Data I/S
+ * Copyright (C) 1995-1998, Index Data I/S
* See the file LICENSE for details.
* Sebastian Hammer, Adam Dickmeiss
*
* $Log: session.h,v $
- * Revision 1.12 1997-09-01 08:53:01 adam
+ * Revision 1.13 1998-01-29 13:30:23 adam
+ * Better event handle system for NT/Unix.
+ *
+ * Revision 1.12 1997/09/01 08:53:01 adam
* New windows NT/95 port using MSV5.0. The test server 'ztest' was
* moved a separate directory. MSV5.0 project server.dsp created.
* As an option, the server can now operate as an NT service.
int preferredMessageSize;
int maximumRecordSize;
int version; /* highest version-bit set (2 or 3) */
+
+ int (*bend_sort) ();
} association;
association *create_association(IOCHAN channel, COMSTACK link);
/*
- * Copyright (c) 1995-1997, Index Data
+ * Copyright (c) 1995-1998, Index Data
* See the file LICENSE for details.
* Sebastian Hammer, Adam Dickmeiss
*
* Chas Woodfield, Fretwell Downing Datasystem.
*
* $Log: statserv.c,v $
- * Revision 1.44 1997-11-07 13:31:52 adam
+ * Revision 1.45 1998-01-29 13:30:23 adam
+ * Better event handle system for NT/Unix.
+ *
+ * Revision 1.44 1997/11/07 13:31:52 adam
* Added NT Service name part of statserv_options_block. Moved NT
* service utility to server library.
*
#include <errno.h>
#include <options.h>
-#include "eventl.h"
-#include "session.h"
#include <comstack.h>
#include <tcpip.h>
#ifdef USE_XTIMOSI
#include <xmosi.h>
#endif
#include <log.h>
+#include "eventl.h"
+#include "session.h"
#include <statserv.h>
-static IOCHAN pListener;
+static IOCHAN pListener = NULL;
static char *me = "statserver";
/*
typedef struct _ThreadList ThreadList;
-typedef struct _ThreadList
+struct _ThreadList
{
HANDLE hThread;
IOCHAN pIOChannel;
ThreadList *pNext;
-} ThreadList;
+};
static ThreadList *pFirstThread;
static CRITICAL_SECTION Thread_CritSect;
}
}
+int __stdcall event_loop_thread (IOCHAN iochan)
+{
+ return event_loop (&iochan);
+}
+
static void listener(IOCHAN h, int event)
{
COMSTACK line = (COMSTACK) iochan_getdata(h);
#endif
/* Now what we need todo is create a new thread with this iochan as
the parameter */
- /* if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)event_loop, new_chan,
- 0, &ThreadId) == NULL) */
+ /* if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)event_loop_thread,
+ new_chan, 0, &ThreadId) == NULL) */
/* Somehow, somewhere we need to store this thread id, otherwise we won't be
able to close cleanly */
- NewHandle = (HANDLE)_beginthreadex(NULL, 0, event_loop, new_chan, 0, &ThreadId);
+ NewHandle = (HANDLE)_beginthreadex(NULL, 0, event_loop_thread,
+ new_chan, 0, &ThreadId);
if (NewHandle == (HANDLE)-1)
{
void statserv_closedown()
{
- /* We don't need todoanything here - or do we */
- if (pListener != NULL)
- iochan_destroy(pListener);
+ IOCHAN p;
+ for (p = pListener; p; p = p->next)
+ iochan_destroy(p);
}
static void listener(IOCHAN h, int event)
close(hand[0]);
child = 1;
- for (pp = iochan_getchan(); pp; pp = iochan_getnext(pp))
+ for (pp = pListener; pp; pp = iochan_getnext(pp))
{
if (pp != h)
{
{
IOCHAN pp;
/* close our half of the listener socket */
- for (pp = iochan_getchan(); pp; pp = iochan_getnext(pp))
+ for (pp = pListener; pp; pp = iochan_getnext(pp))
{
COMSTACK l = iochan_getdata(pp);
cs_close(l);
iochan_destroy(h);
return;
}
+ new_chan->next = pListener;
+ pListener = new_chan;
if (!(newas = create_association(new_chan, new_line)))
{
logf(LOG_FATAL, "Failed to create new assoc.");
memcpy(&control_block, block, sizeof(*block));
}
-
int statserv_start(int argc, char **argv)
{
int ret, listeners = 0, inetd = 0, r;
}
if ((pListener == NULL) && *control_block.default_listen)
- add_listener(control_block.default_listen, protocol);
+ add_listener(control_block.default_listen, protocol);
#ifndef WINDOWS
if (inetd)
if (pListener == NULL)
ret = 1;
else
- ret = event_loop(pListener);
+ ret = event_loop(&pListener);
nmem_exit ();
return ret;
}