From 8caa5a124f21ce80bd6a4a02576bf00d38096d32 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 3 Aug 1995 13:22:54 +0000 Subject: [PATCH] Request queue. --- ir-tcl.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++-------------- ir-tclp.h | 25 ++++++++++++--------- queue.c | 54 ++++++++++++++++++++++++++------------------ tclmain.c | 8 +++++-- 4 files changed, 111 insertions(+), 51 deletions(-) diff --git a/ir-tcl.c b/ir-tcl.c index 7f9fc2f..ddd1cbd 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -5,7 +5,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.50 1995-07-20 08:09:49 adam + * Revision 1.51 1995-08-03 13:22:54 adam + * Request queue. + * + * Revision 1.50 1995/07/20 08:09:49 adam * client.tcl: Targets removed from hotTargets list when targets * are removed/modified. * ir-tcl.c: More work on triggerResourceControl. @@ -516,6 +519,7 @@ static void get_referenceId (char **dst, Z_ReferenceId *src) /* ------------------------------------------------------- */ +#if 0 /* * ir-tcl_send_APDU: send APDU */ @@ -548,6 +552,7 @@ static int ir_tcl_send_APDU (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu, logf (LOG_DEBUG, "Sent whole %s (%d bytes)", msg, p->slen); return TCL_OK; } +#endif /* * do_init_request: init method on IR object @@ -1007,11 +1012,11 @@ static int do_connect (void *obj, Tcl_Interp *interp, if (r == 1) { ir_select_add_write (cs_fileno (p->cs_link), p); - p->connectFlag = 1; + p->state = IR_TCL_R_Connecting; } else { - p->connectFlag = 0; + p->state = IR_TCL_R_Idle; if (p->callback) IrTcl_eval (p->interp, p->callback); } @@ -1029,7 +1034,7 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, if (argc == 0) { - p->connectFlag = 0; + p->state = IR_TCL_R_Idle; p->hostname = NULL; p->cs_link = NULL; return TCL_OK; @@ -1495,8 +1500,6 @@ static void ir_obj_delete (ClientData clientData) odr_destroy (obj->odr_in); odr_destroy (obj->odr_out); odr_destroy (obj->odr_pr); - free (obj->buf_out); - free (obj->buf_in); free (obj); } @@ -1533,14 +1536,11 @@ static int ir_obj_mk (ClientData clientData, Tcl_Interp *interp, obj->odr_in = odr_createmem (ODR_DECODE); obj->odr_out = odr_createmem (ODR_ENCODE); obj->odr_pr = odr_createmem (ODR_PRINT); - - obj->len_out = 10000; - if (!(obj->buf_out = ir_malloc (interp, obj->len_out))) - return TCL_ERROR; - odr_setbuf (obj->odr_out, obj->buf_out, obj->len_out, 0); + obj->state = IR_TCL_R_Idle; obj->len_in = 0; obj->buf_in = NULL; + obj->request_queue = NULL; tab[0].tab = ir_method_tab; tab[0].obj = obj; @@ -2920,7 +2920,7 @@ void ir_select_read (ClientData clientData) Z_APDU *apdu; int r; - if (p->connectFlag) + if (p->state == IR_TCL_R_Connecting) { r = cs_rcvconnect (p->cs_link); if (r == 1) @@ -2928,7 +2928,7 @@ void ir_select_read (ClientData clientData) logf (LOG_WARN, "cs_rcvconnect returned 1"); return; } - p->connectFlag = 0; + p->state = IR_TCL_R_Idle; ir_select_remove_write (cs_fileno (p->cs_link), p); if (r < 0) { @@ -2943,12 +2943,15 @@ void ir_select_read (ClientData clientData) } if (p->callback) IrTcl_eval (p->interp, p->callback); + if (p->cs_link && p->request_queue) + ir_tcl_send_q (p, p->request_queue, "x"); return; } do { /* signal one more use of ir object - callbacks must not release the ir memory (p pointer) */ + p->state = IR_TCL_R_Reading; ++(p->ref_count); if ((r=cs_get (p->cs_link, &p->buf_in, &p->len_in)) <= 0) { @@ -2961,7 +2964,7 @@ void ir_select_read (ClientData clientData) } do_disconnect (p, NULL, 2, NULL); - /* relase ir object now if callback deleted it */ + /* release ir object now if callback deleted it */ ir_obj_delete (p); return; } @@ -3007,6 +3010,21 @@ void ir_select_read (ClientData clientData) do_disconnect (p, NULL, 2, NULL); } odr_reset (p->odr_in); + if (p->request_queue) /* remove queue entry */ + { + IrTcl_Request *rq; + rq = p->request_queue; + p->request_queue = rq->next; + free (rq->buf_out); + free (rq); + if (!p->request_queue) + p->state = IR_TCL_R_Idle; + } + else + { + logf (LOG_FATAL, "Internal error. No queue entry"); + exit (1); + } if (p->callback) IrTcl_eval (p->interp, p->callback); if (p->ref_count == 1) @@ -3015,7 +3033,9 @@ void ir_select_read (ClientData clientData) return; } --(p->ref_count); - } while (p->cs_link && cs_more (p->cs_link)); + } while (p->cs_link && cs_more (p->cs_link)); + if (p->cs_link && p->request_queue) + ir_tcl_send_q (p, p->request_queue, "x"); } /* @@ -3025,14 +3045,15 @@ void ir_select_write (ClientData clientData) { IrTcl_Obj *p = clientData; int r; + IrTcl_Request *rq; logf (LOG_DEBUG, "In write handler"); - if (p->connectFlag) + if (p->state == IR_TCL_R_Connecting) { r = cs_rcvconnect (p->cs_link); if (r == 1) return; - p->connectFlag = 0; + p->state = IR_TCL_R_Idle; if (r < 0) { logf (LOG_DEBUG, "cs_rcvconnect error"); @@ -3050,6 +3071,7 @@ void ir_select_write (ClientData clientData) IrTcl_eval (p->interp, p->callback); return; } +#if 0 if ((r=cs_put (p->cs_link, p->sbuf, p->slen)) < 0) { logf (LOG_DEBUG, "select write fail"); @@ -3060,9 +3082,28 @@ void ir_select_write (ClientData clientData) } do_disconnect (p, NULL, 2, NULL); } +#else + rq = p->request_queue; + assert (rq); + if ((r=cs_put (p->cs_link, rq->buf_out, rq->len_out)) < 0) + { + logf (LOG_DEBUG, "select write fail"); + if (p->failback) + { + p->failInfo = IR_TCL_FAIL_WRITE; + IrTcl_eval (p->interp, p->failback); + } + free (rq->buf_out); + rq->buf_out = NULL; + do_disconnect (p, NULL, 2, NULL); + } +#endif else if (r == 0) /* remove select bit */ { + p->state = IR_TCL_R_Waiting; ir_select_remove_write (cs_fileno (p->cs_link), p); + free (rq->buf_out); + rq->buf_out = NULL; } } diff --git a/ir-tclp.h b/ir-tclp.h index e5b03b6..dc1c143 100644 --- a/ir-tclp.h +++ b/ir-tclp.h @@ -5,7 +5,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tclp.h,v $ - * Revision 1.12 1995-07-28 10:28:38 adam + * Revision 1.13 1995-08-03 13:23:00 adam + * Request queue. + * + * Revision 1.12 1995/07/28 10:28:38 adam * First work on request queue. * * Revision 1.11 1995/06/20 08:07:35 adam @@ -96,9 +99,10 @@ typedef struct { char *cs_type; int protocol_type; - int connectFlag; int failInfo; COMSTACK cs_link; + + int state; int preferredMessageSize; int maximumRecordSize; @@ -121,12 +125,12 @@ typedef struct { char *hostname; - char *buf_out; - int len_out; char *buf_in; int len_in; +#if 0 char *sbuf; int slen; +#endif ODR odr_in; ODR odr_out; ODR odr_pr; @@ -152,13 +156,10 @@ typedef struct IrTcl_Request_ { char *buf_out; int len_out; - char *buf_in; - int len_in; char *callback; char *failback; - int state; } IrTcl_Request; typedef struct { @@ -243,8 +244,10 @@ struct ir_named_entry { int ir_tcl_get_marc (Tcl_Interp *interp, const char *buf, int argc, char **argv); -int ir_tcl_send (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu, - const char *msg); +int ir_tcl_send_APDU (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu, + const char *msg); +int ir_tcl_send_q (IrTcl_Obj *p, IrTcl_Request *rq, const char *msg); + char *ir_tcl_fread_marc (FILE *inf, size_t *size); #define IR_TCL_FAIL_CONNECT 1 @@ -253,7 +256,9 @@ char *ir_tcl_fread_marc (FILE *inf, size_t *size); #define IR_TCL_FAIL_IN_APDU 4 #define IR_TCL_FAIL_UNKNOWN_APDU 5 -#define IR_TCL_R_Queue 0 +#define IR_TCL_R_Idle 0 #define IR_TCL_R_Writing 1 #define IR_TCL_R_Waiting 2 +#define IR_TCL_R_Reading 3 +#define IR_TCL_R_Connecting 4 #endif diff --git a/queue.c b/queue.c index 29c2b65..1d416d2 100644 --- a/queue.c +++ b/queue.c @@ -6,7 +6,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: queue.c,v $ - * Revision 1.1 1995-07-28 10:28:39 adam + * Revision 1.2 1995-08-03 13:23:01 adam + * Request queue. + * + * Revision 1.1 1995/07/28 10:28:39 adam * First work on request queue. * */ @@ -29,11 +32,10 @@ void *ir_tcl_malloc (size_t size) return p; } -int ir_tcl_send (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu, - const char *msg) +int ir_tcl_send_APDU (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu, + const char *msg) { IrTcl_Request **rp; - int empty; if (!z_APDU (p->odr_out, &apdu, 0)) { @@ -43,35 +45,43 @@ int ir_tcl_send (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu, return TCL_ERROR; } rp = &p->request_queue; - empty = *rp ? 0 : 1; while (*rp) rp = &(*rp)->next; *rp = ir_tcl_malloc (sizeof(**rp)); (*rp)->next = NULL; - (*rp)->state = IR_TCL_R_Queue; (*rp)->buf_out = odr_getbuf (p->odr_out, &(*rp)->len_out, NULL); + odr_setbuf (p->odr_out, NULL, 0, 1); odr_reset (p->odr_out); - if (empty) + if (p->state == IR_TCL_R_Idle) { - int r; - - r = cs_put (p->cs_link, (*rp)->buf_out, (*rp)->len_out); - if (r < 0) + if (ir_tcl_send_q (p, *rp, msg) == TCL_ERROR) { sprintf (interp->result, "cs_put failed in %s", msg); return TCL_ERROR; } - else if (r == 1) - { - ir_select_add_write (cs_fileno (p->cs_link), p); - logf (LOG_DEBUG, "Send part of %s", msg); - (*rp)->state = IR_TCL_R_Writing; - } - else - { - logf (LOG_DEBUG, "Send %s (%d bytes)", msg, (*rp)->len_out); - (*rp)->state = IR_TCL_R_Waiting; - } + } + return TCL_OK; +} + +int ir_tcl_send_q (IrTcl_Obj *p, IrTcl_Request *rp, const char *msg) +{ + int r; + + r = cs_put (p->cs_link, rp->buf_out, rp->len_out); + if (r < 0) + return TCL_ERROR; + else if (r == 1) + { + ir_select_add_write (cs_fileno (p->cs_link), p); + logf (LOG_DEBUG, "Send part of %s", msg); + p->state = IR_TCL_R_Writing; + } + else + { + logf (LOG_DEBUG, "Send %s (%d bytes)", msg, rp->len_out); + p->state = IR_TCL_R_Waiting; + free (rp->buf_out); + rp->buf_out = NULL; } return TCL_OK; } diff --git a/tclmain.c b/tclmain.c index 214ce9a..0bfe572 100644 --- a/tclmain.c +++ b/tclmain.c @@ -5,7 +5,10 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: tclmain.c,v $ - * Revision 1.10 1995-06-30 12:39:28 adam + * Revision 1.11 1995-08-03 13:23:02 adam + * Request queue. + * + * Revision 1.10 1995/06/30 12:39:28 adam * Bug fix: loadFile didn't set record type. * The MARC routines are a little less strict in the interpretation. * Script display.tcl replaces the old marc.tcl. @@ -42,7 +45,7 @@ #include #include - +#include #include "ir-tcl.h" static char *fileName = NULL; @@ -81,6 +84,7 @@ int main (int argc, char **argv) if (argc == 2) fileName = argv[1]; + log_init (LOG_ALL, "", NULL); if (Tcl_AppInit(interp) != TCL_OK) { fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result); } -- 1.7.10.4