]> andersk Git - moira.git/blame - gdb/gdb_ops.c
split userreg & reg_svr into separate directories
[moira.git] / gdb / gdb_ops.c
CommitLineData
5580185e 1/*
2 * $Source$
3 * $Header$
4 */
5
6#ifndef lint
7static char *rcsid_gdb_ops_c = "$Header$";
8#endif lint
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30/************************************************************************/
31/*
32/* gdb_ops.c
33/*
34/* GDB - Asynchronous Operations and Their Synchronous
35/* Counterparts
36/*
37/* Author: Noah Mendelsohn
38/* Copyright: 1986 MIT Project Athena
39/*
40/* These routines provide a suite of asynchronous operations
41/* on connections.
42/*
43/************************************************************************/
44
45#include <stdio.h>
46#include "gdb.h"
47#include <netinet/in.h>
48#include <sys/ioctl.h>
49#ifdef vax
50extern u_long htonl();
51#endif vax
52\f
53/************************************************************************/
54/*
55/* send_object (send_object)
56/*
57/* Synchronous form of start_sending_object. Returns either
58/* OP_CANCELLED, or OP_RESULT(op).
59/*
60/************************************************************************/
61
62int
63send_object(con, objp, type)
64CONNECTION con;
65char *objp;
66int type;
67{
68 register OPERATION op;
69 register int retval;
70
71
72 op = create_operation();
73 start_sending_object(op, con, objp, type);
74 (void) complete_operation(op);
75 if (OP_STATUS(op) == OP_COMPLETE)
76 retval = OP_RESULT(op);
77 else
78 retval = OP_STATUS(op);
79 delete_operation(op);
80 return retval;
81}
82\f
83/************************************************************************/
84/*
85/* start_send_object (g_snobj)
86/*
87/* Start the asynchronous transmission of a gdb object.
88/* Note that this routine must be passed the address of the object,
89/* not the object itself.
90/*
91/* The following three routines work together, and may be considered
92/* as a single entity implementing the operation. The first merely
93/* saves away its arguments and queues the operation on the designated
94/* connection. These stay there until they percolate to the head of
95/* the queue. The second is the initialization routine, which is
96/* called by the connection maintenance logic when the operation
97/* first reaches the head of the queue. This routine encodes
98/* the supplied data for transmission, and then sends it. If the
99/* transmission executes synchronously, then the third routine is
100/* called immediately to clean up. If not, the third routine is
101/* marked as the 'continuation' routine, which will cause its
102/* invocation when the transmission completes.
103/*
104/* The data is preceded by its length expressed as a long in
105/* network byte order.
106/*
107/************************************************************************/
108
109struct obj_data {
110 char *objp; /* address of the object to */
111 /* be sent */
112 int type; /* type code for the object */
113 /* to be sent*/
114 char *flattened; /* address of first byte */
115 /* of flattened data */
116 int len; /* length of the flattened */
117 /* data */
118};
119
120int g_isnobj();
121int g_csnobj();
122
123int
124start_sending_object(op, con, objp, type)
125OPERATION op;
126CONNECTION con;
127char *objp;
128int type;
129{
130 struct obj_data *arg;
131
132 /*
133 * Make sure the supplied connection is a legal one
134 */
135 GDB_CHECK_CON(con, "start_sending_object")
136 GDB_CHECK_OP(op, "start_sending_object")
137
138 arg = (struct obj_data *)db_alloc(sizeof(struct obj_data));
139
140 arg->objp = objp;
141 arg->type = type;
142 initialize_operation(op, g_isnobj, (char *)arg, (int (*)())NULL);
143 (void) queue_operation(con, CON_OUTPUT, op);
144}
145
146 /*----------------------------------------------------------*/
147 /*
148 /* g_isnobj
149 /*
150 /* Init routine for sending an object. This routine is
151 /* called by the connection management logic when the send
152 /* request percolates to the top of the queue. This routine
153 /* reformats the data into an appropriate form for transmission.
154 /* The format used is a length, represented as a long in
155 /* network byte order, followed by the data itself. The
156 /* continuation routine below is called, either synchronously
157 /* or asynchronously, once the transmission is complete.
158 /*
159 /*----------------------------------------------------------*/
160
161int
162g_isnobj(op, hcon, arg)
163OPERATION op;
164HALF_CONNECTION hcon;
165struct obj_data *arg;
166{
167 /*
168 * Find out the encoded length of the data
169 */
170 arg->len = FCN_PROPERTY(arg->type, CODED_LENGTH_PROPERTY)
171 (arg->objp, hcon);
172
173 /*
174 * Allocate space and flatten (encode) the data
175 */
176 arg->flattened = db_alloc(arg->len+sizeof(long));
177 *(u_long *)arg->flattened = htonl((u_long)arg->len);
178
179 FCN_PROPERTY(arg->type, ENCODE_PROPERTY)
180 (arg->objp, hcon, arg->flattened+sizeof(long));
181
182 /*
183 * Set up continuation routine in case it's needed after the return
184 */
185 op->fcn.cont = g_csnobj;
186
187 /*
188 * Start sending the data, maybe even complete
189 */
190 if (gdb_send_data(hcon, arg->flattened, arg->len + sizeof(long)) ==
191 OP_COMPLETE) {
192 return g_csnobj(op, hcon, arg) ;/* this return is a little */
193 /* subtle. As continuation */
194 /* routines call each other */
195 /* synchronously, the last */
196 /* one determines whether we */
197 /* completed or are still */
198 /* running. That status */
199 /* percolates back through */
200 /* the entire call chain. */
201 } else {
202 return OP_RUNNING;
203 }
204}
205
206
207
208
209
210
211 /*----------------------------------------------------------*/
212 /*
213 /* g_csnobj
214 /*
215 /* Continuation routine for sending an object. Since there is
216 /* only one transmission, started by the init routine, this is
217 /* called when that transmission is done, and it does all the
218 /* associated clean up.
219 /*
220 /*----------------------------------------------------------*/
221
222int
223g_csnobj(op, hcon, arg)
224OPERATION op;
225HALF_CONNECTION hcon;
226struct obj_data *arg;
227{
228 op->result = OP_SUCCESS;
229 db_free((char *)arg->flattened, arg->len + sizeof(long));
230 /* free the sent data */
231 db_free((char *)arg, sizeof(struct obj_data)); /* free the state structure */
232 return OP_COMPLETE;
233}
234
235\f
236/************************************************************************/
237/*
238/* receive_object (receive_object)
239/*
240/* Synchronous form of start_receiving_object. Returns either
241/* OP_CANCELLED, or OP_RESULT(op).
242/*
243/************************************************************************/
244
245int
246receive_object(con, objp, type)
247CONNECTION con;
248char *objp;
249int type;
250{
251 register OPERATION op;
252 register int retval;
253
254 op = create_operation();
255 start_receiving_object(op, con, objp, type);
256 (void) complete_operation(op);
257 if (OP_STATUS(op) == OP_COMPLETE)
258 retval = OP_RESULT(op);
259 else
260 retval = OP_STATUS(op);
261 delete_operation(op);
262 return retval;
263}
264\f
265/************************************************************************/
266/*
267/* start_receiving_object (g_rcobj)
268/*
269/* Start the asynchronous receipt of a gdb object. Note that this
270/* routine must be passed the address of the object, not the object
271/* itself. In the case of structured objects, this routine may
272/* allocate the necessary storage. The work to build the object is
273/* done by the object's decode routine.
274/*
275/* The following three routines work together, and may be considered
276/* as a single entity implementing the operation. The first merely
277/* saves away its arguments and queues the operation on the designated
278/* connection. These stay there until they percolate to the head of
279/* the queue. The second is the initialization routine, which is
280/* called by the connection maintenance logic when the operation
281/* first reaches the head of the queue. This routine initiates a read
282/* for the length of the object, and sets up a continuation routine
283/* to read the object itself. When the object itself has been read, it
284/* is decoded and the operation completes.
285/*
286/* The data is preceded by its length expressed as a long in
287/* network byte order.
288/*
289/* preempt_and_start_receiving_object (g_prcobj)
290/*
291/* Similar to above, but may be called only from an active operation
292/* (i.e. an init or continue routine) on an inbound half connection.
293/* The receive effectively pre-empts the old operation, which wil
294/* continue after the receive is done.
295/*
296/*
297/************************************************************************/
298
299struct robj_data {
300 char *objp; /* address of the object to */
301 /* be received */
302 int type; /* type code for the object */
303 /* to be received */
304 char *flattened; /* address of first byte */
305 /* of flattened data */
306 int len; /* length of the flattened */
307 /* data */
308};
309
310int g_ircobj();
311int g_c1rcobj();
312int g_c2rcobj();
313
314 /*----------------------------------------------------------*/
315 /*
316 /* start_receiving_object
317 /*
318 /*----------------------------------------------------------*/
319
320int
321start_receiving_object(op, con, objp, type)
322OPERATION op;
323CONNECTION con;
324char *objp;
325int type;
326{
327 struct robj_data *arg;
328
329 /*
330 * Make sure the supplied connection is a legal one
331 */
332 GDB_CHECK_CON(con, "start_receiving_object")
333 GDB_CHECK_OP(op, "start_receiving_object")
334
335 arg = (struct robj_data *)db_alloc(sizeof(struct robj_data));
336
337 arg->objp = objp;
338 arg->type = type;
339 initialize_operation(op, g_ircobj, (char *)arg, (int (*)())NULL);
340 (void) queue_operation(con, CON_INPUT, op);
341}
342
343 /*----------------------------------------------------------*/
344 /*
345 /* preempt_and_start_receiving_object
346 /*
347 /*----------------------------------------------------------*/
348
349int
350preempt_and_start_receiving_object(op, oldop, objp, type)
351OPERATION op;
352OPERATION oldop;
353char *objp;
354int type;
355{
356 struct robj_data *arg;
357
358 /*
359 * Make sure the supplied connection is a legal one
360 */
361 GDB_CHECK_OP(op, "preempt_and_start_receiving_object")
362 GDB_CHECK_OP(oldop, "preempt_and_start_receiving_object")
363
364 arg = (struct robj_data *)db_alloc(sizeof(struct robj_data));
365
366 arg->objp = objp;
367 arg->type = type;
368 initialize_operation(op, g_ircobj, (char *)arg, (int (*)())NULL);
369 (void) g_preempt_me(oldop, op);
370}
371
372 /*----------------------------------------------------------*/
373 /*
374 /* g_ircobj
375 /*
376 /* Initialization routine for receiving an object.
377 /* Called when the receive operation percolates to the
378 /* top of the queue. First, we must receive the single
379 /* 'long' which carries the length of the rest of the data.
380 /* We do that now, either synchronously or asynchronously.
381 /*
382 /*----------------------------------------------------------*/
383
384int
385g_ircobj(op, hcon, arg)
386OPERATION op;
387HALF_CONNECTION hcon;
388struct robj_data *arg;
389{
390 op->fcn.cont = g_c1rcobj;
391 if(gdb_receive_data(hcon, (char *)&(arg->len), sizeof(long)) == OP_COMPLETE) {
392 return g_c1rcobj(op, hcon, arg);/* this return is a little */
393 /* subtle. As continuation */
394 /* routines call each other */
395 /* synchronously, the last */
396 /* one determines whether we */
397 /* completed or are still */
398 /* running. That status */
399 /* percolates back through */
400 /* the entire call chain. */
401 } else {
402 return OP_RUNNING;
403 }
404}
405
406 /*----------------------------------------------------------*/
407 /*
408 /* g_c1rcobj
409 /*
410 /* At this point, we have received the length. Now, allocate
411 /* the space for the rest of the data, and start receiving
412 /* it.
413 /*
414 /*----------------------------------------------------------*/
415
416int
417g_c1rcobj(op, hcon, arg)
418OPERATION op;
419HALF_CONNECTION hcon;
420struct robj_data *arg;
421{
422#ifdef vax
423 extern u_long ntohl();
424#endif vax
425
426 /*
427 * Now we know the length of the encoded data, convert the length
428 * to local byte order, and allocate the space for the receive.
429 */
430 arg->len = (int) ntohl((u_long)arg->len);
431
432 arg->flattened = db_alloc(arg->len);
433 /*
434 * Now start receiving the encoded object itself. If it all comes in
435 * synchronously, then just go on to the c2 routine to decode it and
436 * finish up. Else return OP_RUNNING, so the rest of the system
437 * can get some work done while we wait.
438 */
439 op->fcn.cont = g_c2rcobj;
440 if(gdb_receive_data(hcon, arg->flattened, arg->len ) == OP_COMPLETE) {
441 return g_c2rcobj(op, hcon, arg);
442 } else {
443 return OP_RUNNING;
444 }
445}
446
447 /*----------------------------------------------------------*/
448 /*
449 /* g_c2rcobj
450 /*
451 /* At this point, all the data has been received. Decode
452 /* it into the place provided by the caller, free all
453 /* temporarily allocated memory, and return.
454 /*
455 /*----------------------------------------------------------*/
456
457int
458g_c2rcobj(op, hcon, arg)
459OPERATION op;
460HALF_CONNECTION hcon;
461struct robj_data *arg;
462{
463 /*
464 * Decode the received data into local representation.
465 */
466 FCN_PROPERTY(arg->type, DECODE_PROPERTY)
467 (arg->objp, hcon, arg->flattened);
468 op->result = OP_SUCCESS;
469 db_free(arg->flattened, arg->len); /* free the received data */
470 db_free((char *)arg, sizeof(struct robj_data)); /* free the state structure */
471 return OP_COMPLETE;
472}
473\f
474/************************************************************************/
475/*
476/* complete_operation(complete_operation)
477/*
478/* Wait for a given operation to complete, allowing everything
479/* to progress in the meantime. Returns the last known status
480/* of the operation, which in general will be OP_COMPLETE unless
481/* errors were encountered (and this version of the code doesn't
482/* do error handing right anyway!)
483/*
484/* We do this by (1) calling gdb_progress to assure that all
485/* possible progress has been made, which is always a good thing
486/* to do when we get the chance and (2) looping on calls to
487/* con_select, which will make all possible future progress,
488/* but without burning cycles unnecessarily in the process.
489/*
490/************************************************************************/
491
492int
493complete_operation(op)
494OPERATION op;
495{
496 (void) gdb_progress();
497
498 while(op->status != OP_COMPLETE && op->status != OP_CANCELLED)
499 (void) con_select(0, (fd_set *)NULL, (fd_set *)NULL,
500 (fd_set *)NULL, (struct timeval *)NULL);
501
502 return op->status;
503
504}
505
506\f
507/************************************************************************/
508/*
509/* cancel_operation(cancel_operation)
510/*
511/* Attempts to cancel an operation.
512/*
513/************************************************************************/
514
515int
516cancel_operation(op)
517OPERATION op;
518{
519 register HALF_CONNECTION hcon = op->halfcon;
520
521 if (op->status != OP_RUNNING && op->status != OP_QUEUED)
522 return op->status;
523
524 if (hcon == NULL)
525 GDB_GIVEUP("cancel_operation: operation is queued but half connection is unknown")
526
527 /*
528 * If we're at the head of the queue and running, then we have to
529 * call the cancelation routine for this particular operation so
530 * it can clean up.
531 */
532 if (op->prev == (OPERATION)hcon) {
533 if (op->status == OP_RUNNING && op->cancel != NULL)
534 (*op->cancel)(op->halfcon, op->arg);
535 }
536
537 /*
538 * Looks safe, now cancel it.
539 */
540 op->next->prev = op->prev; /* de-q it */
541 op->prev->next = op->next; /* " " " */
542 op->status = OP_CANCELLED;
543 op->halfcon = NULL;
544
545 return OP_CANCELLED;
546}
547\f
548/************************************************************************/
549/*
550/* start_listening
551/*
552/* Start the asynchronous acquisition of a connection. This
553/* results in the queuing of a GDB "OPERATION" to do the
554/* requested listening.
555/*
556/************************************************************************/
557
558struct lis_data {
559 char *otherside; /* data returned from an */
560 /* accept */
561 int *otherlen; /* length of the otherside */
562 /* field */
563 int *fdp; /* ptr to the fd of the */
564 /* newly accepted */
565 /* connection */
566};
567
568int g_ilis();
569int g_clis();
570
571int
572gdb_start_listening(op, con, otherside, lenp, fdp)
573OPERATION op;
574CONNECTION con;
575char *otherside;
576int *lenp;
577int *fdp;
578{
579 struct lis_data *arg;
580
581 GDB_INIT_CHECK
582
583 /*
584 * Make sure the supplied connection is a legal one
585 */
586 GDB_CHECK_CON(con, "start_listening")
587 GDB_CHECK_OP(op, "start_listening")
588
589 arg = (struct lis_data *)db_alloc(sizeof(struct lis_data));
590
591 arg->otherside = otherside;
592 arg->otherlen = lenp;
593 arg->fdp = fdp;
594 initialize_operation(op, g_ilis, (char *)arg, (int (*)())NULL);
595 (void) queue_operation(con, CON_INPUT, op);
596}
597
598 /*----------------------------------------------------------*/
599 /*
600 /* g_ilis
601 /*
602 /* Init routine for doing a listen.
603 /*
604 /*----------------------------------------------------------*/
605
606int
607g_ilis(op, hcon, arg)
608OPERATION op;
609HALF_CONNECTION hcon;
610struct lis_data *arg;
611{
612 int rc;
613
614 /*
615 * Set up continuation routine in case it's needed after the return
616 */
617 op->fcn.cont = g_clis;
618
619 /*
620 * Try doing the listen now, and then decide whether to go
621 * right on to the continuation routine or to let things hang
622 * for the moment.
623 */
624 rc = gdb_start_a_listen(hcon, arg->otherside, arg->otherlen, arg->fdp);
625 if (rc==OP_COMPLETE) {
626 return g_clis(op, hcon, arg); /* this return is a little */
627 /* subtle. As continuation */
628 /* routines call each other */
629 /* synchronously, the last */
630 /* one determines whether we */
631 /* completed or are still */
632 /* running. That status */
633 /* percolates back through */
634 /* the entire call chain. */
635 } else {
636 return OP_RUNNING;
637 }
638}
639
640
641
642 /*----------------------------------------------------------*/
643 /*
644 /* g_clis
645 /*
646 /* Continuation routine for accepting a connection.
647 /*
648 /* At this point, the fd has been accepted and all
649 /* the necessary information given back to the caller.
650 /*
651 /*----------------------------------------------------------*/
652
653int
654g_clis(op, hcon, arg)
655OPERATION op;
656HALF_CONNECTION hcon;
657struct lis_data *arg;
658{
659 op->result = OP_SUCCESS;
660 db_free((char *)arg, sizeof(struct lis_data));
661 /* free the state structure */
662 return OP_COMPLETE;
663}
664
665\f
666/************************************************************************/
667/*
668/* start_accepting_client
669/*
670/* Start the asynchronous acquisition of a client. This queueable
671/* operation first tries to accept a connection. On this connection,
672/* it reads a startup string from the client, and then completes.
673/*
674/* The return values from this are not quite what you might expect.
675/* In general, the operation will show complete, rather than cancelled,
676/* if it gets as far as creating the new connection at all. If
677/* subsequent activities result in errors from system calls, then
678/* this operation will complete with a status of OP_COMPLETE and a
679/* result of OP_CANCELLED. In this case, the applications IS given
680/* a connection descriptor for the new connection, and that descriptor
681/* has an errno value indicating why the failure occurred. The
682/* caller must then sever this connection to free the descriptor.
683/*
684/************************************************************************/
685
686struct acc_data {
687 char *otherside; /* data returned from an */
688 /* accept */
689 int *otherlen; /* length of the otherside */
690 /* field */
691 OPERATION listenop; /* used to listen for */
692 /* the fd */
693 OPERATION receiveop; /* used when receiving */
694 /* tuple from the client */
695 CONNECTION con; /* the connection we're */
696 /* trying to create */
697 CONNECTION *conp; /* this is where the caller */
698 /* wants the connection */
699 /* returned */
700 TUPLE *tuplep; /* pointer to tuple we */
701 /* are going to receive */
702 /* from new client */
703};
704
705int g_iacc();
706int g_i2acc();
707
708int
709start_accepting_client(listencon, op, conp, otherside, lenp, tuplep)
710CONNECTION listencon;
711OPERATION op;
712CONNECTION *conp;
713char *otherside;
714int *lenp;
715TUPLE *tuplep;
716{
717 struct acc_data *arg;
718
719 GDB_INIT_CHECK
720
721 /*
722 * Make sure the supplied connection and operation are legal
723 */
724 GDB_CHECK_CON(listencon, "start_accepting_client")
725 GDB_CHECK_OP(op, "start_accepting_client")
726
727 arg = (struct acc_data *)db_alloc(sizeof(struct acc_data));
728
729 arg->otherside = otherside;
730 arg->otherlen = lenp;
731 arg->conp = conp;
732 *conp = NULL; /* in case we fail */
733 arg->listenop = create_operation();
734 arg->receiveop = create_operation();
735 arg->con = g_make_con();
736 arg->tuplep = tuplep;
737 *tuplep = NULL; /* in case we fail */
738
739 /*
740 * Queue an operation ahead of us which will accept an fd and
741 * put it in arg->con->in. As a byproduct, pick up the from
742 * information that we return to the caller.
743 */
744 gdb_start_listening(arg->listenop, listencon,
745 arg->otherside,
746 arg->otherlen, &(arg->con->in.fd));
747
748 /*
749 * Now queue us behind it. By the time we run our init routine,
750 * a connection should have been acquired.
751 */
752 initialize_operation(op, g_iacc, (char *)arg, (int (*)())NULL);
753 (void) queue_operation(listencon, CON_INPUT, op);
754}
755
756 /*----------------------------------------------------------*/
757 /*
758 /* g_iacc
759 /*
760 /* Init routine for accepting a connection. By the
761 /* time this runs, the listen has been done, the
762 /* 'from' data put in position for the caller, and
763 /* the fd plugged into the connection descriptor.
764 /* If all went well, fill out the connection descriptor
765 /* and then requeue us on that to do the receive of
766 /* the requested tuple.
767 /*
768 /*----------------------------------------------------------*/
769
770int
771g_iacc(op, hcon, arg)
772OPERATION op;
773HALF_CONNECTION hcon;
774struct acc_data *arg;
775{
776 register CONNECTION con = arg->con;
777
778 /*
779 * Set up 2nd init routine for after we re-queue ourselves
780 */
781 op->fcn.cont = g_i2acc;
782 /*
783 * See whether we successfully accepted a connection. If
784 * not, we just cancel ourselves. If so, fill out the
785 * connection descriptor and related data structures properly,
786 * then requeue ourselves on the new connection.
787 */
788 if (OP_STATUS(arg->listenop) != OP_COMPLETE ||
789 OP_RESULT(arg->listenop) != OP_SUCCESS ||
790 con->in.fd <=0) {
791 (void) sever_connection(con);
792 g_clnup_accept(arg);
793 op->result = OP_CANCELLED;
794 return OP_CANCELLED;
795 }
796
797 /*
798 * OK, we got an fd, but the connection and related structures
799 * aren't really set up straight, and the fd must be put
800 * into non-blocking mode. There really should be a common
801 * routine for this, since some of the logic exists in 2
802 * or 3 places.
803 */
804 con->status = CON_STARTING;
805 con->out.fd = con->in.fd;
806 g_ver_iprotocol(con); /* make sure we're at */
807 /* same level of protocol */
808 if (con->status == CON_UP) {
809 /*
810 * We've successfully started the connection, now mark
811 * it for non-blocking I/O. Also, update the high water
812 * mark of fd's controlled by our system.
813 */
814 int nb = 1;
815 if(ioctl(con->in.fd, FIONBIO, (char *)&nb)== (-1)) {
816 g_stop_with_errno(con);
817 *arg->conp = con; /* give failed con to */
818 /* caller so he can find */
819 /* errno */
820 gdb_perror("gdb: ioctl for non-block failed");
821 g_clnup_accept(arg);
822 op->result = OP_CANCELLED; /* we didn't really, but */
823 /* we want caller to look */
824 /* at the connection so he */
825 /* can find errno*/
826 return OP_COMPLETE;
827 }
828 if (con->in.fd +1 > gdb_mfd)
829 gdb_mfd = con->in.fd + 1;
830 /*
831 * Allocate a buffer, if necessary, and reset buffer pointers
832 * so first request will result in a long read into the buffer
833 */
834 g_allocate_connection_buffers(con);
835
836 } else {
837 *arg->conp = con; /* give failed con to */
838 /* caller so he can find */
839 /* errno */
840 g_clnup_accept(arg);
841 op->result = OP_CANCELLED;
842 return OP_COMPLETE;
843 }
844
845 /*
846 * Before we requeue ourselves on the new connection, queue
847 * up a receive for the expected tuple. Then we'll be
848 * sure that it's there by the time we run.
849 */
850 start_receiving_object(arg->receiveop, con, (char *)(arg->tuplep),
851 TUPLE_T);
852 /*
853 * Requeue ourselves behind the receive operation.
854 */
855
856 (void) requeue_operation(con, CON_INPUT, op);
857 return OP_REQUEUED;
858}
859
860
861
862 /*----------------------------------------------------------*/
863 /*
864 /* g_i2acc
865 /*
866 /* Second init routine for accepting a connection.
867 /* This one is run after the operation is requeued on
868 /* the new connection. By the time we run here, the
869 /* attempt to receive the tuple has already been made.
870 /* We just check on status and clean-up.
871 /*
872 /*----------------------------------------------------------*/
873
874int
875g_i2acc(op, hcon, arg)
876OPERATION op;
877HALF_CONNECTION hcon;
878struct acc_data *arg;
879{
880 int rc;
881
882 rc = OP_STATUS(arg->receiveop); /* if it completes, then */
883 /* so do we! */
884 *arg->conp = arg->con; /* give caller the new con */
885 if (rc != OP_COMPLETE)
886 (void) g_stop_connection(arg->con);
887 /*
888 * Release all transient data structures.
889 */
890 g_clnup_accept(arg);
891
892 return OP_COMPLETE;
893}
894
895 /*----------------------------------------------------------*/
896 /*
897 /* g_clnup_accept
898 /*
899 /* Free all data structures used by start_accepting_client.
900 /*
901 /*----------------------------------------------------------*/
902
903int
904g_clnup_accept(arg)
905struct acc_data *arg;
906{
907 delete_operation(arg->listenop);
908 delete_operation(arg->receiveop);
909 db_free((char *)arg, sizeof(struct acc_data));
910}
This page took 0.217048 seconds and 5 git commands to generate.