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