comp.lang.ada
 help / color / mirror / Atom feed
From: Darren New <dnew@san.rr.com>
Subject: Dynamic dispatch again
Date: Sat, 06 Oct 2001 01:08:49 GMT
Date: 2001-10-06T01:08:49+00:00	[thread overview]
Message-ID: <3BBE5993.1CF0069D@san.rr.com> (raw)

OK, I'm still trying to figure out how to make one entry call wind up
calling code in different units.

It seems to me that if I have a line that says

  requeue thing.do_it

then there's only one unit in which this can be requeued. That is,
there's no way to declare "thing" such that it might point to different
implementations of something, as it could if it was a tagged type. 

Basically, what I'm looking for is a method whereby a task can wait for
one of N entries to be called, take action as appropriate, and have a
driver program have M of these tasks but all running different code. 

Essentially, I have a basic manager task doing I/O, distributing
messages to "profiles". Each "profile" can get the same set of messages
(start, stop, are you ready, here's a message), but each responds to the
messages in different ways. Some of the calls need to be blocking as
well (like "are you ready") or the programming's gonna be a bear.
There's also a *different* task managing requests from the local side of
the connection.

What I have so far is here, but I can't figure out how to properly
define "profile" such that "dispatch task" or "driver" can call either
"profile_double" or "profile_negative" and get the right answer. Is
there any possibility I'm missing something? I'd hate to have to package
up the entire interface as message-passing when there's routines like
"ask everyone if they're ready", and have to pick up the answers coming
back asynchronously.

Thanks in advance!



+=+=+=+ profile.ads

package profile is
    type profile is tagged limited null record;
    type profile_pointer is access all profile'class;
end profile;

+=+=+=+ profile_double.ads

with profile;

package profile_double is

  task type profile_double_task is 
    entry xlate(in_in : in integer; out_out : out integer);
  end profile_double_task;

  type profile_double is new profile.profile with record 
    tsk : profile_double_task; 
  end record;

end profile_double;

+=+=+=+ profile_double.adb

with profile;

package body profile_double is

    task body profile_double_task is 
    begin
        loop
            select
                accept xlate(in_in : in integer; out_out : out integer)
do
                    out_out := in_in + in_in;
                end xlate;
            or
                terminate;
            end select;
        end loop;
    end profile_double_task;

end profile_double;

+=+=+=+ profile_negate.ads

with profile;

package profile_negate is

  task type profile_negate_task is 
    entry xlate(in_in : in integer; out_out : out integer);
  end profile_negate_task;

  type profile_negate is new profile.profile with record 
    tsk : profile_negate_task; 
  end record;

end profile_negate;

+=+=+=+ profile_negate.adb

with profile;

package body profile_negate is

    task body profile_negate_task is 
    begin
        loop
            select
                accept xlate(in_in : in integer; out_out : out integer)
do
                    out_out := - in_in;
                end xlate;
            or
                terminate;
            end select;
        end loop;
    end profile_negate_task;

end profile_negate;

+=+=+=+ dispatch_task.ads

with Profile;
package Dispatch_Task is

  task type Dispatch_Task is
    entry set_task(p : in profile.profile_pointer);
    entry xlate(in_in : in Integer; out_out : out integer);
  end Dispatch_Task;

  type Dispatch_task_pointer is access all dispatch_task;

end Dispatch_Task;

+=+=+=+ dispatch_task.adb

with profile;

package body dispatch_task is

  task body dispatch_task is
    held_p : profile.Profile_Pointer;
  begin
    accept set_task(p : in profile.Profile_Pointer) do
        held_p := p;
    end set_task;
    loop
        select
            accept xlate(in_in : in integer; out_out : out integer) do
                requeue held_p.tsk;
            end xlate;
        or 
            terminate;
        end select;
    end loop;
  end dispatch_task;

end dispatch_task;

+=+=+=+ driver.adb

with dispatch_task;
with profile;
with profile_double;
with profile_negate;
with Ada.Text_IO;

procedure driver is
    type pat is array(1..2) of dispatch_task.dispatch_task_pointer;
    pa : pat;
    i : integer;
begin
    pa(1) := new dispatch_task.dispatch_task;
    pa(2) := new dispatch_task.dispatch_task;
    pa(1).set_task(new profile_double.profile_double);
    pa(2).set_task(new profile_negate.profile_negate);
    pa(1).xlate(100, i);
    Ada.Text_IO.Put_Line("First, " & Integer'Image(I));
    pa(2).xlate(100, i);
    Ada.Text_IO.Put_Line("Second, " & Integer'Image(I));
end driver;

+=+=+=+



-- 
Darren New 
San Diego, CA, USA (PST). Cryptokeys on demand.
                   Who is this Dr. Ibid anyway, 
                  and how does he know so much?



             reply	other threads:[~2001-10-06  1:08 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-10-06  1:08 Darren New [this message]
2001-10-06 17:52 ` Dynamic dispatch again tmoran
2001-10-08  1:13   ` Darren New
2001-10-08  4:23     ` tmoran
2001-10-08 16:26       ` Darren New
2001-10-08 18:21         ` tmoran
2001-10-08 19:07           ` Darren New
2001-10-09  0:25             ` tmoran
2001-10-09  0:40               ` Darren New
2001-10-09  1:29                 ` Larry Hazel
2001-10-09  4:10                 ` tmoran
2001-10-09 15:40                   ` Darren New
2001-10-09 17:58                     ` tmoran
2001-10-09 19:26                       ` Darren New
2001-10-09 19:42                         ` tmoran
2001-10-09 20:23                           ` Darren New
2001-10-09 22:37                         ` tmoran
2001-10-10 18:17                           ` Darren New
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox