From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.5-pre1 (2020-06-20) on ip-172-31-74-118.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-1.9 required=3.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.5-pre1 Date: 27 Apr 93 16:13:37 GMT From: widget!jgg@uunet.uu.net (John Goodsen) Subject: Re: GUI's generating Ada (was Re: Teleuse) Message-ID: <1993Apr27.161337.18593@evb.com> List-Id: hyler@ast.saic.com (Buffy Hyler) writes: > >I'm curious. For all these GUI's that generate Ada, can I use Ada >tasking within my application code while linked to the GUI generated >interface code? I know that I can do so with Sun's DevGuide/Ada >(XView) (with some limitations), but that some special effort was done >in the Ada XView bindings to allow this. As it was explained to me >(over 2 years ago), X and Ada tasking use the same interupts so some >care must be taken when both are linked in the same application. > There are basically 2 issues at hand here and they are not isolated to X window applications, but most C applications which get Ada bindings put on them: 1) When a UNIX process blocks for I/O or other reasons, *ALL* Ada tasks in that UNIX process are also blocked. 2) Most C libraries, including X/Xt/Motif/Xview are not written to handle multiple threads of control accessing the library within a single process address space (eg. an Ada task). The net result is that library state data can be trashed by more than one Ada task accessing it. This is sometimes referred to as "non-rentrant" code, but is more accurately referred to as "non thread-safe" code (early versions of FORTRAN is an example of non-rentrant code). An example of case #1 is witnessed in the Xtoolkit/Motif/Xview in which a main loop sits on top of an I/O connection and waits for packets of data to come across, which are dispatched as X events (eg. XtMainLoop() ) The C implementation of these loops typically blocks the UNIX process until some data appears, which blocks any other Ada tasks which might be running. The solution to this is quite simple and has been implemented by all serious Motif and Xview binding vendors that I'm aware of. You simply, write you're own main dispatching loop in Ada which peeks at the IO connection before telling the OS to read from it. If nothing is there to read, then the loop executes an Ada delay statement, which lets other tasks execute. Case #2 is more of a problem. Basically, you have to synchronize your tasks to ensure that only one thread of control accesses the library at a time. A *real* Ada binding should perform this synchronization (actually serialization) for you, and alleviate you of the headache. A readers/writers algorithm works, except that you need to be sure to let the same thread of control into the library in the case of recursive, round-trips between the library and the application. To do this, you need the task id of the Ada task (which is not required in the Ada language but provided by some Ada compiler vendors). On a related note, can anyone tell me off-hand if Ada 9X will provide a call like: current_task := CURRENT_TASK_ID; ^^^^^^^^^^^^^^^ A function which returns the current task id. I know you can do the similar thing with task types, but task types require you to have a task identifier ahead of time, which inhibits a portable solution for task safe bindings across multiple compiler vendors. hope this helps -- John Goodsen EVB Software Engineering, Inc. jgg@evb.com - Ada & Object Oriented Training/Products (301) 695-6960 - Ada GUI & Graphics Tools and Training - Software Reuse, Process & Environments