Request queue.
[ir-tcl-moved-to-github.git] / queue.c
1
2 /*
3  * IR toolkit for tcl/tk
4  * (c) Index Data 1995
5  * See the file LICENSE for details.
6  * Sebastian Hammer, Adam Dickmeiss
7  *
8  * $Log: queue.c,v $
9  * Revision 1.2  1995-08-03 13:23:01  adam
10  * Request queue.
11  *
12  * Revision 1.1  1995/07/28  10:28:39  adam
13  * First work on request queue.
14  *
15  */
16
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <ctype.h>
20 #include <assert.h>
21
22 #include "ir-tclp.h"
23
24 void *ir_tcl_malloc (size_t size)
25 {
26     void *p = malloc (size);
27     if (!p)
28     {
29         logf (LOG_FATAL, "Out of memory. %d bytes requested", size);
30         exit (1);
31     }
32     return p;
33 }
34
35 int ir_tcl_send_APDU (Tcl_Interp *interp, IrTcl_Obj *p, Z_APDU *apdu,
36                       const char *msg)
37 {
38     IrTcl_Request **rp;
39
40     if (!z_APDU (p->odr_out, &apdu, 0))
41     {
42         Tcl_AppendResult (interp, odr_errlist [odr_geterror (p->odr_out)],
43                           NULL);
44         odr_reset (p->odr_out);
45         return TCL_ERROR;
46     }
47     rp = &p->request_queue;
48     while (*rp)
49         rp = &(*rp)->next;
50     *rp = ir_tcl_malloc (sizeof(**rp));
51     (*rp)->next = NULL;
52     (*rp)->buf_out = odr_getbuf (p->odr_out, &(*rp)->len_out, NULL);
53     odr_setbuf (p->odr_out, NULL, 0, 1);
54     odr_reset (p->odr_out);
55     if (p->state == IR_TCL_R_Idle)
56     {
57         if (ir_tcl_send_q (p, *rp, msg) == TCL_ERROR)
58         {
59             sprintf (interp->result, "cs_put failed in %s", msg);
60             return TCL_ERROR;
61         } 
62     }
63     return TCL_OK;
64 }
65
66 int ir_tcl_send_q (IrTcl_Obj *p, IrTcl_Request *rp, const char *msg)
67 {
68     int r;
69
70     r = cs_put (p->cs_link, rp->buf_out, rp->len_out);
71     if (r < 0)
72         return TCL_ERROR;
73     else if (r == 1)
74     {
75         ir_select_add_write (cs_fileno (p->cs_link), p);
76         logf (LOG_DEBUG, "Send part of %s", msg);
77         p->state = IR_TCL_R_Writing;
78     }
79     else
80     {
81         logf (LOG_DEBUG, "Send %s (%d bytes)", msg, rp->len_out);
82         p->state = IR_TCL_R_Waiting;
83         free (rp->buf_out);
84         rp->buf_out = NULL;
85     }
86     return TCL_OK;
87 }
88