Request queue.
authorAdam Dickmeiss <adam@indexdata.dk>
Thu, 3 Aug 1995 13:22:54 +0000 (13:22 +0000)
committerAdam Dickmeiss <adam@indexdata.dk>
Thu, 3 Aug 1995 13:22:54 +0000 (13:22 +0000)
ir-tcl.c
ir-tclp.h
queue.c
tclmain.c

index 7f9fc2f..ddd1cbd 100644 (file)
--- 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;
     }
 }
 
index e5b03b6..dc1c143 100644 (file)
--- 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 (file)
--- 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;
 }
index 214ce9a..0bfe572 100644 (file)
--- 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 <assert.h>
 
 #include <tcl.h>
-
+#include <log.h>
 #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);
     }