7 static char *rcsid_gdb_ops_c = "$Header$";
30 /************************************************************************/
34 /* GDB - Asynchronous Operations and Their Synchronous
37 /* Author: Noah Mendelsohn
38 /* Copyright: 1986 MIT Project Athena
39 /* For copying and distribution information, please see
40 /* the file <mit-copyright.h>.
42 /* These routines provide a suite of asynchronous operations
45 /************************************************************************/
47 #include <mit-copyright.h>
50 #include <netinet/in.h>
51 #include <sys/ioctl.h>
53 extern u_long htonl();
56 /************************************************************************/
58 /* send_object (send_object)
60 /* Synchronous form of start_sending_object. Returns either
61 /* OP_CANCELLED, or OP_RESULT(op).
63 /************************************************************************/
66 send_object(con, objp, type)
71 register OPERATION op;
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);
81 retval = OP_STATUS(op);
86 /************************************************************************/
88 /* start_send_object (g_snobj)
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.
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.
107 /* The data is preceded by its length expressed as a long in
108 /* network byte order.
110 /************************************************************************/
113 char *objp; /* address of the object to */
115 int type; /* type code for the object */
117 char *flattened; /* address of first byte */
118 /* of flattened data */
119 int len; /* length of the flattened */
127 start_sending_object(op, con, objp, type)
133 struct obj_data *arg;
136 * Make sure the supplied connection is a legal one
138 GDB_CHECK_CON(con, "start_sending_object")
139 GDB_CHECK_OP(op, "start_sending_object")
141 arg = (struct obj_data *)db_alloc(sizeof(struct obj_data));
145 initialize_operation(op, g_isnobj, (char *)arg, (int (*)())NULL);
146 (void) queue_operation(con, CON_OUTPUT, op);
149 /*----------------------------------------------------------*/
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.
162 /*----------------------------------------------------------*/
165 g_isnobj(op, hcon, arg)
167 HALF_CONNECTION hcon;
168 struct obj_data *arg;
171 * Find out the encoded length of the data
173 arg->len = FCN_PROPERTY(arg->type, CODED_LENGTH_PROPERTY)
177 * Allocate space and flatten (encode) the data
179 arg->flattened = db_alloc(arg->len+sizeof(long));
180 *(u_long *)arg->flattened = htonl((u_long)arg->len);
182 FCN_PROPERTY(arg->type, ENCODE_PROPERTY)
183 (arg->objp, hcon, arg->flattened+sizeof(long));
186 * Set up continuation routine in case it's needed after the return
188 op->fcn.cont = g_csnobj;
191 * Start sending the data, maybe even complete
193 if (gdb_send_data(hcon, arg->flattened, arg->len + sizeof(long)) ==
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. */
214 /*----------------------------------------------------------*/
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.
223 /*----------------------------------------------------------*/
226 g_csnobj(op, hcon, arg)
228 HALF_CONNECTION hcon;
229 struct obj_data *arg;
231 op->result = OP_SUCCESS;
232 db_free((char *)arg->flattened, arg->len + sizeof(long));
233 /* free the sent data */
234 db_free((char *)arg, sizeof(struct obj_data)); /* free the state structure */
239 /************************************************************************/
241 /* receive_object (receive_object)
243 /* Synchronous form of start_receiving_object. Returns either
244 /* OP_CANCELLED, or OP_RESULT(op).
246 /************************************************************************/
249 receive_object(con, objp, type)
254 register OPERATION op;
257 op = create_operation();
258 start_receiving_object(op, con, objp, type);
259 (void) complete_operation(op);
260 if (OP_STATUS(op) == OP_COMPLETE)
261 retval = OP_RESULT(op);
263 retval = OP_STATUS(op);
264 delete_operation(op);
268 /************************************************************************/
270 /* start_receiving_object (g_rcobj)
272 /* Start the asynchronous receipt of a gdb object. Note that this
273 /* routine must be passed the address of the object, not the object
274 /* itself. In the case of structured objects, this routine may
275 /* allocate the necessary storage. The work to build the object is
276 /* done by the object's decode routine.
278 /* The following three routines work together, and may be considered
279 /* as a single entity implementing the operation. The first merely
280 /* saves away its arguments and queues the operation on the designated
281 /* connection. These stay there until they percolate to the head of
282 /* the queue. The second is the initialization routine, which is
283 /* called by the connection maintenance logic when the operation
284 /* first reaches the head of the queue. This routine initiates a read
285 /* for the length of the object, and sets up a continuation routine
286 /* to read the object itself. When the object itself has been read, it
287 /* is decoded and the operation completes.
289 /* The data is preceded by its length expressed as a long in
290 /* network byte order.
292 /* preempt_and_start_receiving_object (g_prcobj)
294 /* Similar to above, but may be called only from an active operation
295 /* (i.e. an init or continue routine) on an inbound half connection.
296 /* The receive effectively pre-empts the old operation, which wil
297 /* continue after the receive is done.
300 /************************************************************************/
303 char *objp; /* address of the object to */
305 int type; /* type code for the object */
307 char *flattened; /* address of first byte */
308 /* of flattened data */
309 int len; /* length of the flattened */
317 /*----------------------------------------------------------*/
319 /* start_receiving_object
321 /*----------------------------------------------------------*/
324 start_receiving_object(op, con, objp, type)
330 struct robj_data *arg;
333 * Make sure the supplied connection is a legal one
335 GDB_CHECK_CON(con, "start_receiving_object")
336 GDB_CHECK_OP(op, "start_receiving_object")
338 arg = (struct robj_data *)db_alloc(sizeof(struct robj_data));
342 initialize_operation(op, g_ircobj, (char *)arg, (int (*)())NULL);
343 (void) queue_operation(con, CON_INPUT, op);
346 /*----------------------------------------------------------*/
348 /* preempt_and_start_receiving_object
350 /*----------------------------------------------------------*/
353 preempt_and_start_receiving_object(op, oldop, objp, type)
359 struct robj_data *arg;
362 * Make sure the supplied connection is a legal one
364 GDB_CHECK_OP(op, "preempt_and_start_receiving_object")
365 GDB_CHECK_OP(oldop, "preempt_and_start_receiving_object")
367 arg = (struct robj_data *)db_alloc(sizeof(struct robj_data));
371 initialize_operation(op, g_ircobj, (char *)arg, (int (*)())NULL);
372 (void) g_preempt_me(oldop, op);
375 /*----------------------------------------------------------*/
379 /* Initialization routine for receiving an object.
380 /* Called when the receive operation percolates to the
381 /* top of the queue. First, we must receive the single
382 /* 'long' which carries the length of the rest of the data.
383 /* We do that now, either synchronously or asynchronously.
385 /*----------------------------------------------------------*/
388 g_ircobj(op, hcon, arg)
390 HALF_CONNECTION hcon;
391 struct robj_data *arg;
393 op->fcn.cont = g_c1rcobj;
394 if(gdb_receive_data(hcon, (char *)&(arg->len), sizeof(long)) == OP_COMPLETE) {
395 return g_c1rcobj(op, hcon, arg);/* this return is a little */
396 /* subtle. As continuation */
397 /* routines call each other */
398 /* synchronously, the last */
399 /* one determines whether we */
400 /* completed or are still */
401 /* running. That status */
402 /* percolates back through */
403 /* the entire call chain. */
409 /*----------------------------------------------------------*/
413 /* At this point, we have received the length. Now, allocate
414 /* the space for the rest of the data, and start receiving
417 /*----------------------------------------------------------*/
420 g_c1rcobj(op, hcon, arg)
422 HALF_CONNECTION hcon;
423 struct robj_data *arg;
426 extern u_long ntohl();
430 * Now we know the length of the encoded data, convert the length
431 * to local byte order, and allocate the space for the receive.
433 arg->len = (int) ntohl((u_long)arg->len);
435 arg->flattened = db_alloc(arg->len);
437 * Now start receiving the encoded object itself. If it all comes in
438 * synchronously, then just go on to the c2 routine to decode it and
439 * finish up. Else return OP_RUNNING, so the rest of the system
440 * can get some work done while we wait.
442 op->fcn.cont = g_c2rcobj;
443 if(gdb_receive_data(hcon, arg->flattened, arg->len ) == OP_COMPLETE) {
444 return g_c2rcobj(op, hcon, arg);
450 /*----------------------------------------------------------*/
454 /* At this point, all the data has been received. Decode
455 /* it into the place provided by the caller, free all
456 /* temporarily allocated memory, and return.
458 /*----------------------------------------------------------*/
461 g_c2rcobj(op, hcon, arg)
463 HALF_CONNECTION hcon;
464 struct robj_data *arg;
467 * Decode the received data into local representation.
469 FCN_PROPERTY(arg->type, DECODE_PROPERTY)
470 (arg->objp, hcon, arg->flattened);
471 op->result = OP_SUCCESS;
472 db_free(arg->flattened, arg->len); /* free the received data */
473 db_free((char *)arg, sizeof(struct robj_data)); /* free the state structure */
477 /************************************************************************/
479 /* complete_operation(complete_operation)
481 /* Wait for a given operation to complete, allowing everything
482 /* to progress in the meantime. Returns the last known status
483 /* of the operation, which in general will be OP_COMPLETE unless
484 /* errors were encountered (and this version of the code doesn't
485 /* do error handing right anyway!)
487 /* We do this by (1) calling gdb_progress to assure that all
488 /* possible progress has been made, which is always a good thing
489 /* to do when we get the chance and (2) looping on calls to
490 /* con_select, which will make all possible future progress,
491 /* but without burning cycles unnecessarily in the process.
493 /************************************************************************/
496 complete_operation(op)
499 (void) gdb_progress();
501 while(op->status != OP_COMPLETE && op->status != OP_CANCELLED)
502 (void) con_select(0, (fd_set *)NULL, (fd_set *)NULL,
503 (fd_set *)NULL, (struct timeval *)NULL);
510 /************************************************************************/
512 /* cancel_operation(cancel_operation)
514 /* Attempts to cancel an operation.
516 /************************************************************************/
522 register HALF_CONNECTION hcon = op->halfcon;
524 if (op->status != OP_RUNNING && op->status != OP_QUEUED)
528 GDB_GIVEUP("cancel_operation: operation is queued but half connection is unknown")
531 * If we're at the head of the queue and running, then we have to
532 * call the cancelation routine for this particular operation so
535 if (op->prev == (OPERATION)hcon) {
536 if (op->status == OP_RUNNING && op->cancel != NULL)
537 (*op->cancel)(op->halfcon, op->arg);
541 * Looks safe, now cancel it.
543 op->next->prev = op->prev; /* de-q it */
544 op->prev->next = op->next; /* " " " */
545 op->status = OP_CANCELLED;
551 /************************************************************************/
555 /* Start the asynchronous acquisition of a connection. This
556 /* results in the queuing of a GDB "OPERATION" to do the
557 /* requested listening.
559 /************************************************************************/
562 char *otherside; /* data returned from an */
564 int *otherlen; /* length of the otherside */
566 int *fdp; /* ptr to the fd of the */
575 gdb_start_listening(op, con, otherside, lenp, fdp)
582 struct lis_data *arg;
587 * Make sure the supplied connection is a legal one
589 GDB_CHECK_CON(con, "start_listening")
590 GDB_CHECK_OP(op, "start_listening")
592 arg = (struct lis_data *)db_alloc(sizeof(struct lis_data));
594 arg->otherside = otherside;
595 arg->otherlen = lenp;
597 initialize_operation(op, g_ilis, (char *)arg, (int (*)())NULL);
598 (void) queue_operation(con, CON_INPUT, op);
601 /*----------------------------------------------------------*/
605 /* Init routine for doing a listen.
607 /*----------------------------------------------------------*/
610 g_ilis(op, hcon, arg)
612 HALF_CONNECTION hcon;
613 struct lis_data *arg;
618 * Set up continuation routine in case it's needed after the return
620 op->fcn.cont = g_clis;
623 * Try doing the listen now, and then decide whether to go
624 * right on to the continuation routine or to let things hang
627 rc = gdb_start_a_listen(hcon, arg->otherside, arg->otherlen, arg->fdp);
628 if (rc==OP_COMPLETE) {
629 return g_clis(op, hcon, arg); /* this return is a little */
630 /* subtle. As continuation */
631 /* routines call each other */
632 /* synchronously, the last */
633 /* one determines whether we */
634 /* completed or are still */
635 /* running. That status */
636 /* percolates back through */
637 /* the entire call chain. */
645 /*----------------------------------------------------------*/
649 /* Continuation routine for accepting a connection.
651 /* At this point, the fd has been accepted and all
652 /* the necessary information given back to the caller.
654 /*----------------------------------------------------------*/
657 g_clis(op, hcon, arg)
659 HALF_CONNECTION hcon;
660 struct lis_data *arg;
662 op->result = OP_SUCCESS;
663 db_free((char *)arg, sizeof(struct lis_data));
664 /* free the state structure */
669 /************************************************************************/
671 /* start_accepting_client
673 /* Start the asynchronous acquisition of a client. This queueable
674 /* operation first tries to accept a connection. On this connection,
675 /* it reads a startup string from the client, and then completes.
677 /* The return values from this are not quite what you might expect.
678 /* In general, the operation will show complete, rather than cancelled,
679 /* if it gets as far as creating the new connection at all. If
680 /* subsequent activities result in errors from system calls, then
681 /* this operation will complete with a status of OP_COMPLETE and a
682 /* result of OP_CANCELLED. In this case, the applications IS given
683 /* a connection descriptor for the new connection, and that descriptor
684 /* has an errno value indicating why the failure occurred. The
685 /* caller must then sever this connection to free the descriptor.
687 /************************************************************************/
690 char *otherside; /* data returned from an */
692 int *otherlen; /* length of the otherside */
694 OPERATION listenop; /* used to listen for */
696 OPERATION receiveop; /* used when receiving */
697 /* tuple from the client */
698 CONNECTION con; /* the connection we're */
699 /* trying to create */
700 CONNECTION *conp; /* this is where the caller */
701 /* wants the connection */
703 TUPLE *tuplep; /* pointer to tuple we */
704 /* are going to receive */
705 /* from new client */
712 start_accepting_client(listencon, op, conp, otherside, lenp, tuplep)
713 CONNECTION listencon;
720 struct acc_data *arg;
725 * Make sure the supplied connection and operation are legal
727 GDB_CHECK_CON(listencon, "start_accepting_client")
728 GDB_CHECK_OP(op, "start_accepting_client")
730 arg = (struct acc_data *)db_alloc(sizeof(struct acc_data));
732 arg->otherside = otherside;
733 arg->otherlen = lenp;
735 *conp = NULL; /* in case we fail */
736 arg->listenop = create_operation();
737 arg->receiveop = create_operation();
738 arg->con = g_make_con();
739 arg->tuplep = tuplep;
740 *tuplep = NULL; /* in case we fail */
743 * Queue an operation ahead of us which will accept an fd and
744 * put it in arg->con->in. As a byproduct, pick up the from
745 * information that we return to the caller.
747 gdb_start_listening(arg->listenop, listencon,
749 arg->otherlen, &(arg->con->in.fd));
752 * Now queue us behind it. By the time we run our init routine,
753 * a connection should have been acquired.
755 initialize_operation(op, g_iacc, (char *)arg, (int (*)())NULL);
756 (void) queue_operation(listencon, CON_INPUT, op);
759 /*----------------------------------------------------------*/
763 /* Init routine for accepting a connection. By the
764 /* time this runs, the listen has been done, the
765 /* 'from' data put in position for the caller, and
766 /* the fd plugged into the connection descriptor.
767 /* If all went well, fill out the connection descriptor
768 /* and then requeue us on that to do the receive of
769 /* the requested tuple.
771 /*----------------------------------------------------------*/
774 g_iacc(op, hcon, arg)
776 HALF_CONNECTION hcon;
777 struct acc_data *arg;
779 register CONNECTION con = arg->con;
782 * Set up 2nd init routine for after we re-queue ourselves
784 op->fcn.cont = g_i2acc;
786 * See whether we successfully accepted a connection. If
787 * not, we just cancel ourselves. If so, fill out the
788 * connection descriptor and related data structures properly,
789 * then requeue ourselves on the new connection.
791 if (OP_STATUS(arg->listenop) != OP_COMPLETE ||
792 OP_RESULT(arg->listenop) != OP_SUCCESS ||
794 (void) sever_connection(con);
796 op->result = OP_CANCELLED;
801 * OK, we got an fd, but the connection and related structures
802 * aren't really set up straight, and the fd must be put
803 * into non-blocking mode. There really should be a common
804 * routine for this, since some of the logic exists in 2
807 con->status = CON_STARTING;
808 con->out.fd = con->in.fd;
809 g_ver_iprotocol(con); /* make sure we're at */
810 /* same level of protocol */
811 if (con->status == CON_UP) {
813 * We've successfully started the connection, now mark
814 * it for non-blocking I/O. Also, update the high water
815 * mark of fd's controlled by our system.
818 if(ioctl(con->in.fd, FIONBIO, (char *)&nb)== (-1)) {
819 g_stop_with_errno(con);
820 *arg->conp = con; /* give failed con to */
821 /* caller so he can find */
823 gdb_perror("gdb: ioctl for non-block failed");
825 op->result = OP_CANCELLED; /* we didn't really, but */
826 /* we want caller to look */
827 /* at the connection so he */
831 if (con->in.fd +1 > gdb_mfd)
832 gdb_mfd = con->in.fd + 1;
834 * Allocate a buffer, if necessary, and reset buffer pointers
835 * so first request will result in a long read into the buffer
837 g_allocate_connection_buffers(con);
840 *arg->conp = con; /* give failed con to */
841 /* caller so he can find */
844 op->result = OP_CANCELLED;
849 * Before we requeue ourselves on the new connection, queue
850 * up a receive for the expected tuple. Then we'll be
851 * sure that it's there by the time we run.
853 start_receiving_object(arg->receiveop, con, (char *)(arg->tuplep),
856 * Requeue ourselves behind the receive operation.
859 (void) requeue_operation(con, CON_INPUT, op);
865 /*----------------------------------------------------------*/
869 /* Second init routine for accepting a connection.
870 /* This one is run after the operation is requeued on
871 /* the new connection. By the time we run here, the
872 /* attempt to receive the tuple has already been made.
873 /* We just check on status and clean-up.
875 /*----------------------------------------------------------*/
878 g_i2acc(op, hcon, arg)
880 HALF_CONNECTION hcon;
881 struct acc_data *arg;
885 rc = OP_STATUS(arg->receiveop); /* if it completes, then */
887 *arg->conp = arg->con; /* give caller the new con */
888 if (rc != OP_COMPLETE)
889 (void) g_stop_connection(arg->con);
891 * Release all transient data structures.
898 /*----------------------------------------------------------*/
902 /* Free all data structures used by start_accepting_client.
904 /*----------------------------------------------------------*/
908 struct acc_data *arg;
910 delete_operation(arg->listenop);
911 delete_operation(arg->receiveop);
912 db_free((char *)arg, sizeof(struct acc_data));