comp.lang.ada
 help / color / mirror / Atom feed
* "C - like: THIS" pointer to a task type inside a task function
@ 2012-01-23 19:32 Ada BRL
  2012-01-23 19:59 ` Dmitry A. Kazakov
                   ` (3 more replies)
  0 siblings, 4 replies; 19+ messages in thread
From: Ada BRL @ 2012-01-23 19:32 UTC (permalink / raw)


Dear all,

I'm experiencing an issue about local and not local pointers...

I've N clients and one server that communicate each other.
The N clients retrieve data dynamically, send it to the server throgh
enrty call (obviously the server can accept just one call per time)
and wait for the reply from the server (through accept statement).
For this reason the server needs to know on which client call the
entry:
one time could be the 3th, another the 1st and so on...

This is my - deeply simplified - framework:

package P1 is

	task type T1 is
		entry Retrieve_Data(Data : String);
	end T1;


	task type T2 is
		entry Retrieve_Data(Data : String);
	end T2;


	task type T3 is
		entry Retrieve_Data(Data : String);
	end T3;


end P1;

package body P1 is

	task body T1 is

		Data : String;

	begin
		while True loop

			-- retrieve somehow data

			T4.Send_Data(Data);

			accept Retrieve_Data(Data);

		end loop;
	end T1;


	task body T2 is

		Data : String;

	begin
		while True loop

			-- retrieve somehow data

			T4.Send_Data(Data);

			accept Retrieve_Data(Data);

		end loop;
	end T2;


	task body T3 is

		Data : String;

	begin
		while True loop

			-- retrieve somehow data

			T4.Send_Data(Data);

			accept Retrieve_Data(Data);

		end loop;
	end T3;

end P1;


-- other file


package P2 is

	task type T4 is
		entry Send_Data(Data : String; Ti : task_pointer_type);
	end T4;
end P2;

package body P2 is

	task body T4 is

		Data : String;

	begin
		while True loop

			accept Send_Data(Data, Ti) do -- ===> Problem here! How can I
retrieve Ti object. I think I need a "this" pointer inside the task
body. Ti has to notify T4 who's the sender of data.

			-- do some stuff

			end Send_Data;

			Ti.Retrieve_Data(Data); -- ===> Problem here! How can I retrieve Ti
object

		end loop;
	end T4;

end P2;

I thought to create a task interface (because abstract types for tasks
are illegal) in order to use a dynamic dispatching inside Send_Data,
in the example identified by the "i" index of Task.


--- other file

package P_Interface

	type Tsk is task interface;
	type Tsk_ptr is access all Tsk'Class;

end P_Interface;

I've tried in so many ways (inserting local types into the tasks,
outiside, into the interface, using explicit casting and so on) to get
the things working but without any good outcomes...
I even had some problems of circular dependency but eventually I've
solved them with "limited with" directive.
No problems (for this moment =) ) for the T4 reference.

May you help me, please =)?
I think this is a quite common problem and so I'm optimistic to
receive some useful replies!

Thank you very much!



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:32 "C - like: THIS" pointer to a task type inside a task function Ada BRL
@ 2012-01-23 19:59 ` Dmitry A. Kazakov
  2012-01-23 22:17   ` tmoran
                     ` (2 more replies)
  2012-01-23 20:20 ` Jeffrey Carter
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-23 19:59 UTC (permalink / raw)


On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:

> I've N clients and one server that communicate each other.
> The N clients retrieve data dynamically, send it to the server throgh
> enrty call (obviously the server can accept just one call per time)
> and wait for the reply from the server (through accept statement).

A server cannot wait for itself either "through accept statement" or any
other way.

   T4.Send_Data (Data);
   accept Retrieve_Data (Data);

is a patented way to run into a deadlock.

> For this reason the server needs to know on which client call the
> entry:

That does not follow. Why do the server need to know the caller?

> package P1 is
> 
> 	task type T1 is
> 		entry Retrieve_Data(Data : String);

   entry Exchange_Data (Data : in out String);

An entry can have in, out, in-out parameters like a subprogram call. You
can pass parameters in and get the results out, just in one call.

> I think this is a quite common problem and so I'm optimistic to
> receive some useful replies!

It is considered bad design when two components know each other. Usually
the software is designed in a way that component relationships are
asymmetric, e.g. the callee knows nothing about the caller. Component knows
nothing about the container, etc. The advantage of this approach is its
robustness. You can have as many callers you need without changing the
callee. Imagine, that sine from the math library would have to be modified
each time somebody writes a program calling it. For concurrency symmetric
relationships impose an additional risk of deadlocking.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:32 "C - like: THIS" pointer to a task type inside a task function Ada BRL
  2012-01-23 19:59 ` Dmitry A. Kazakov
@ 2012-01-23 20:20 ` Jeffrey Carter
  2012-01-24 17:13   ` Ada BRL
  2012-01-24  6:39 ` J-P. Rosen
  2012-01-25  0:42 ` Adam Beneschan
  3 siblings, 1 reply; 19+ messages in thread
From: Jeffrey Carter @ 2012-01-23 20:20 UTC (permalink / raw)


On 01/23/2012 12:32 PM, Ada BRL wrote:

I think perhaps you should become more familiar with basic Ada before attempting 
something like this. In addition to the use of "in out" parameters already 
suggested, creating multiple objects of a task type is better than having 
multiple singleton tasks.

> 		Data : String;

This is illegal.

> 		while True loop

"loop" all by itself has the same effect, and is clearer.

-- 
Jeff Carter
"I was hobbling along, minding my own business, all of a
sudden, up he comes, cures me! One minute I'm a leper with
a trade, next minute my livelihood's gone! Not so much as a
'by your leave!' You're cured, mate. Bloody do-gooder!"
Monty Python's Life of Brian
76

--- Posted via news://freenews.netfront.net/ - Complaints to news@netfront.net ---



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:59 ` Dmitry A. Kazakov
@ 2012-01-23 22:17   ` tmoran
  2012-01-24  8:47     ` Dmitry A. Kazakov
  2012-01-24 17:12   ` Ada BRL
  2012-01-24 17:27   ` Ada BRL
  2 siblings, 1 reply; 19+ messages in thread
From: tmoran @ 2012-01-23 22:17 UTC (permalink / raw)


> An entry can have in, out, in-out parameters like a subprogram call. You
> can pass parameters in and get the results out, just in one call.

  If the client task, after giving work to the server, needs to do things
other than wait for a result, then adding an "out" parameter won't work.

> It is considered bad design when two components know each other. Usually
> the software is designed in a way that component relationships are
> asymmetric, e.g. the callee knows nothing about the caller. Component knows
> nothing about the container, etc. The advantage of this approach is its
> robustness. You can have as many callers you need without changing the
> callee.

  True, but if the server really does need to call the client, it will
need to know the "name" of the client.  You can do this with
Ada.Task_Identification:

with Ada.Task_Identification;
procedure Testti is

  task type Clients is
    entry Get_Result(Result  : in     Character);
  end Clients;

  task Server is
    entry Get_Work(Work    : in     Character);
  end Server;

  task body Clients is
    Generated_Result: Character;
  begin
    for Jobs in 1 .. 5 loop -- we do want eventual termination of this demo!
      -- generate some work todo, then
      Server.Get_Work(Work => 'w');
      -- do other stuff, then ask for the results
      select
        accept Get_Result(Result  : in     Character) do
          Generated_Result := Result;
        end Get_Result;
        -- use Generated_Result
      or
        terminate; -- Server is dead!  Don't just hang around.  Die.
      end select;
    end loop;
  end Clients;

  Client_List: array (1 .. 10) of Clients;

  task body Server is
    use type Ada.Task_Identification.Task_Id;
    Todo    : Character;
    Result  : Character;
    Source  : Ada.Task_Identification.Task_Id;
  begin
    loop
      select
        accept Get_Work(Work    : in     Character) do
          Todo := Work;
          Source := Get_Work'Caller;
        end Get_Work;
      or
        terminate;
      end select;
      -- handle Todo, generating Result, then pass it back to Source client.
      for I in Client_List'range loop
        if Client_List(I)'Identity = Source then
          Client_List(I).Get_Result(Result);
          exit;
        end if;
        -- if a task other than one in Client_List gave us work, toss it.
      end loop;
    end loop;
  end Server;

begin
  null;  -- Client_List and Server tasks are working away...
end Testti;



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:32 "C - like: THIS" pointer to a task type inside a task function Ada BRL
  2012-01-23 19:59 ` Dmitry A. Kazakov
  2012-01-23 20:20 ` Jeffrey Carter
@ 2012-01-24  6:39 ` J-P. Rosen
  2012-01-25  0:42 ` Adam Beneschan
  3 siblings, 0 replies; 19+ messages in thread
From: J-P. Rosen @ 2012-01-24  6:39 UTC (permalink / raw)


Le 23/01/2012 20:32, Ada BRL a �crit :

I too have concerns about your design, but to answer your specific question:
> 			accept Send_Data(Data, Ti) do -- ===> Problem here! How can I
> retrieve Ti object. I think I need a "this" pointer inside the task
> body. Ti has to notify T4 who's the sender of data.
> 
Inside the body of T1 (or any task type), the name T1 acts as a "this",
i.e. it is not interpreted as a task type, but as a name that designate
the current task. If all your clients are of the same type, use an
access to this task type and T1'access can be used as a pointer to the
current task.

If you need several task types, use a pointer to an interface that all
task types implement.

But there can be many other solutions, assuming you really need
two-stage communication. F.E., if know you have a limited number of
clients, Retrieve_Data could be turned into an entry family, and
Send_Data would provide a token (index into the entry family) where the
client would retrieve its own data. This way, it's always the client who
calls the server.
-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 22:17   ` tmoran
@ 2012-01-24  8:47     ` Dmitry A. Kazakov
  0 siblings, 0 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-24  8:47 UTC (permalink / raw)


On Mon, 23 Jan 2012 22:17:00 +0000 (UTC), tmoran@acm.org wrote:

>> An entry can have in, out, in-out parameters like a subprogram call. You
>> can pass parameters in and get the results out, just in one call.
> 
>   If the client task, after giving work to the server, needs to do things
> other than wait for a result, then adding an "out" parameter won't work.

Yes, but that would not be a N-to-1 service then. The case you are
describing is rather N-to-M, when a task may queue several requests to 1..M
servers and later wait for completion of these requests as needed.

The solution of this problem is not in identifying the caller and then
engaging a rendezvous back to it, but rather the classical one: the request
is a proper ADT. The client task queues the requests which contain the
parameters and/or results. When the task needs the results it waits for the
request to complete.

   protected type Item_Of_Work is
 [    procedure Set_Parameters (...);  ]
      function Get_Result return ...;
      entry Wait_For_Completion;
 [    procedure/entry Cancel; -- Don't want this anymore  ]
   end Item_Of_Work;

   task type Server is
      entry Queue (Request : in out Item_Of_Work);
   end Server;

   ...
   Server_1.Queue (This);
   Server_2.Queue (That);
   ...
   This.Wait_For_Completion;
   
-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:59 ` Dmitry A. Kazakov
  2012-01-23 22:17   ` tmoran
@ 2012-01-24 17:12   ` Ada BRL
  2012-01-24 18:43     ` Dmitry A. Kazakov
  2012-01-24 17:27   ` Ada BRL
  2 siblings, 1 reply; 19+ messages in thread
From: Ada BRL @ 2012-01-24 17:12 UTC (permalink / raw)


On 23 Gen, 19:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:
> > I've N clients and one server that communicate each other.
> > The N clients retrieve data dynamically, send it to the server throgh
> > enrty call (obviously the server can accept just one call per time)
> > and wait for the reply from the server (through accept statement).
>
> A server cannot wait for itself either "through accept statement" or any
> other way.
>
>    T4.Send_Data (Data);
>    accept Retrieve_Data (Data);
>
> is a patented way to run into a deadlock.
>
yes...you are right ... sorry ... =( BUT I MADE A MISTAKE!!!

There are two tasks for every communication channel:
- one performing input, so retrieving data from the net and sending it
to the server (call it T1_IN, T2_IN, ...)
- one performing output, so retrieving data from the server and
sending it on the net (call it T1_OUT, T2_OUT, ...)

> > For this reason the server needs to know on which client call the
> > entry:
>
> That does not follow. Why do the server need to know the caller?

The server has to call the right "output" according to the matching
"input":
received data from T2_IN, server has to send data to T2_OUT and not T1
or T3...

>
> > package P1 is
>
> >    task type T1 is
> >            entry Retrieve_Data(Data : String);
>
>    entry Exchange_Data (Data : in out String);
>
> An entry can have in, out, in-out parameters like a subprogram call. You
> can pass parameters in and get the results out, just in one call.
>
For the reasons above I cannot use in out.

> > I think this is a quite common problem and so I'm optimistic to
> > receive some useful replies!
>
> It is considered bad design when two components know each other. Usually
> the software is designed in a way that component relationships are
> asymmetric, e.g. the callee knows nothing about the caller. Component knows
> nothing about the container, etc. The advantage of this approach is its
> robustness. You can have as many callers you need without changing the
> callee. Imagine, that sine from the math library would have to be modified
> each time somebody writes a program calling it. For concurrency symmetric
> relationships impose an additional risk of deadlocking.

Thank you very much.

>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 20:20 ` Jeffrey Carter
@ 2012-01-24 17:13   ` Ada BRL
  0 siblings, 0 replies; 19+ messages in thread
From: Ada BRL @ 2012-01-24 17:13 UTC (permalink / raw)


On 23 Gen, 20:20, Jeffrey Carter <spam.jrcarter....@spam.not.acm.org>
wrote:
> On 01/23/2012 12:32 PM, Ada BRL wrote:
>
> I think perhaps you should become more familiar with basic Ada before attempting
> something like this. In addition to the use of "in out" parameters already
> suggested, creating multiple objects of a task type is better than having
> multiple singleton tasks.
>
> >            Data : String;
>
> This is illegal.

I know, was just an example, not a copy paste of my code :-).

>
> >            while True loop
>
> "loop" all by itself has the same effect, and is clearer.

See above.

>
> --
> Jeff Carter
> "I was hobbling along, minding my own business, all of a
> sudden, up he comes, cures me! One minute I'm a leper with
> a trade, next minute my livelihood's gone! Not so much as a
> 'by your leave!' You're cured, mate. Bloody do-gooder!"
> Monty Python's Life of Brian
> 76
>
> --- Posted via news://freenews.netfront.net/ - Complaints to n...@netfront.net ---




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:59 ` Dmitry A. Kazakov
  2012-01-23 22:17   ` tmoran
  2012-01-24 17:12   ` Ada BRL
@ 2012-01-24 17:27   ` Ada BRL
  2 siblings, 0 replies; 19+ messages in thread
From: Ada BRL @ 2012-01-24 17:27 UTC (permalink / raw)


I have already inserted a post but it isn't visualized yet...

On 23 Gen, 19:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:
> > I've N clients and one server that communicate each other.
> > The N clients retrieve data dynamically, send it to the server throgh
> > enrty call (obviously the server can accept just one call per time)
> > and wait for the reply from the server (through accept statement).
>
> A server cannot wait for itself either "through accept statement" or any
> other way.
>
>    T4.Send_Data (Data);
>    accept Retrieve_Data (Data);
>

I made a mistake, sorry ... :-(

I have two tasks for every channel of communication:
- input task: retrieves data from the net and send it to the server
(call it Ti_IN),
- output task: receives data from the server and send it on the net
(call it Ti_OUT).

For this reason I need:
1) to know who's sending data to the server --> I've already
implemented it with "in" parameter,
2) have a reference to the output threads, in order to call every time
the entry of the correct thread.

For example:
T2_IN calls Server.Send_Data(Data, 2);
Inside the server I have to call T2_OUT.Retrieve_Data(Data);
and NOT the entry on T1_OUT or T3_OUT.

So the entry Retrieve_Data is implemented only by the _OUT tasks.


> is a patented way to run into a deadlock.

I recognize you are definitely true :-)!

>
> > For this reason the server needs to know on which client call the
> > entry:
>
> That does not follow. Why do the server need to know the caller?
>
> > package P1 is
>
> >    task type T1 is
> >            entry Retrieve_Data(Data : String);
>
>    entry Exchange_Data (Data : in out String);
>
> An entry can have in, out, in-out parameters like a subprogram call. You
> can pass parameters in and get the results out, just in one call.
>
> > I think this is a quite common problem and so I'm optimistic to
> > receive some useful replies!
>
> It is considered bad design when two components know each other. Usually
> the software is designed in a way that component relationships are
> asymmetric, e.g. the callee knows nothing about the caller. Component knows
> nothing about the container, etc. The advantage of this approach is its
> robustness. You can have as many callers you need without changing the
> callee. Imagine, that sine from the math library would have to be modified
> each time somebody writes a program calling it. For concurrency symmetric
> relationships impose an additional risk of deadlocking.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thank you very much and sorry for the mistake....but yesterday I have
been programming for lots of hours without any rest...




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-24 17:12   ` Ada BRL
@ 2012-01-24 18:43     ` Dmitry A. Kazakov
  2012-01-25 12:43       ` Ada BRL
  0 siblings, 1 reply; 19+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-24 18:43 UTC (permalink / raw)


On Tue, 24 Jan 2012 09:12:03 -0800 (PST), Ada BRL wrote:

> On 23 Gen, 19:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:
>>> I've N clients and one server that communicate each other.
>>> The N clients retrieve data dynamically, send it to the server throgh
>>> enrty call (obviously the server can accept just one call per time)
>>> and wait for the reply from the server (through accept statement).
>>
>> A server cannot wait for itself either "through accept statement" or any
>> other way.
>>
>> � �T4.Send_Data (Data);
>> � �accept Retrieve_Data (Data);
>>
>> is a patented way to run into a deadlock.
>>
> yes...you are right ... sorry ... =( BUT I MADE A MISTAKE!!!
> 
> There are two tasks for every communication channel:
> - one performing input, so retrieving data from the net and sending it
> to the server (call it T1_IN, T2_IN, ...)
> - one performing output, so retrieving data from the server and
> sending it on the net (call it T1_OUT, T2_OUT, ...)

OK. When you are working with sockets you normally do not need a dedicated
output task. The network stack is already buffered and most likely
asynchronous to the sender once you have initiated send. Thus you could
consider sending data straight out of the server. Note also that unless you
have a relatively small number of sockets to handle (a dozen or so), a task
per socket doing blocking read would not scale. Tasks are used to read
sockets simply because it is easier to program this way. If you have 2-3
sockets, why bother with asynchronous socket I/O? But you won't likely get
a better performance in terms of data throughout and latencies with
separate reader/writer tasks. Having one server engaging rendezvous with
writers that would make this design even less reasonable. That is because
you have the jobs *serialized* in the server. Writers will be either idle
most of the time waiting for the server or else block server, which would
want to make a rendezvous with a *concrete* writer each time. You would
gain nothing from parallelism here, because serialization of processing is
enforced by server, it only appears parallel. Unless there is some
considerable post-processing in the writers, it would rather eat
performance on meaningless task switching.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-23 19:32 "C - like: THIS" pointer to a task type inside a task function Ada BRL
                   ` (2 preceding siblings ...)
  2012-01-24  6:39 ` J-P. Rosen
@ 2012-01-25  0:42 ` Adam Beneschan
  2012-01-25  0:46   ` Adam Beneschan
  2012-01-25  7:38   ` J-P. Rosen
  3 siblings, 2 replies; 19+ messages in thread
From: Adam Beneschan @ 2012-01-25  0:42 UTC (permalink / raw)


On Jan 23, 11:32 am, Ada BRL <ada.brl.2...@gmail.com> wrote:
> Dear all,
>
> I'm experiencing an issue about local and not local pointers...
>
> I've N clients and one server that communicate each other.
> The N clients retrieve data dynamically, send it to the server throgh
> enrty call (obviously the server can accept just one call per time)
> and wait for the reply from the server (through accept statement).
> For this reason the server needs to know on which client call the
> entry:
> one time could be the 3th, another the 1st and so on...

I think you should look into protected types, which may be the best
way to solve your problem (or at least some other problems that may be
like yours).

I'm not sure what exactly you're trying to do, but it sounds something
like this: You have a server and a number of clients.  Each client
may, at some point, initiate a certain kind of request to the server.
The client may want to do other things (OK, that might be Tom's idea
and not yours) and then, when it's done, wait for the request to be
completed and retrieve the result data from the server.

I think the problem is that using "accept" to wait for the server to
complete the request doesn't work very well, especially when your
clients are of several different task types.  There's no way in Ada to
get the server to call a Receive entry without knowing the type of the
task declaring the entry; even if the entries of different task types
all have the same name Receive and the same parameter profile, it just
won't work.  J-P mentioned using interfaces but I think this could get
messy.

A better idea (in my opinion) is to set things up so that the client
will *call* an entry, rather than accept an entry, when it's ready to
wait for the request to be completed.  It can't be an entry in the
server, though, since there's no construct in Ada to "accept" an entry
just from one specific task.  In Ada 83, I would have had the server
create a new, small "helper" task for this purpose; the server would
create a new task when the request is initiated, and later it would
tell that task when the request can be completed, and the client would
wait on that task.  Now, protected types can be used for a similar
purpose.  Something like:

  protected type Request_Control is
     entry Retrieve_Data (Data : String);
     -- other entries that the server would use
  end Request_Control;
  type Request_Control_Acc is access all Request_Control;

Then, the client would do something like:

  Req : Request_Control_Acc;

  loop
     Server.Send_Data (Data, Req);  -- where Req is an OUT parameter
                                    -- to the entry
     -- do some other stuff
     -- then when you're ready to retrieve the result:
     Req.Retrieve_Data (Data);
     -- etc.
  end loop;

The server, when it gets Send_Data, would allocate a new
Request_Control and give the access back to the client.  The server
would also save this access in its own tables so that it can
communicate with it when it's ready to signal that the request is
complete.  Later, the server would call some other operation of
Request_Control when the request is complete, and this would open up
the Retrieve_Data entry so that the client can now unblock (if it is
waiting on Retrieve_Entry) and retrieve the data.

This would also work if your client has two tasks and you want one
task to initiate the request and the other to retrieve the data (I'm
not sure if this is what you meant in one of your later posts).  The
first task would just have to get the Req value to the second task
somehow.

I'll let you read about protected types and figure out how you'd set
them up to make everything work.

Again, I don't know if this is exactly the kind of problem you're
trying to solve, but something like this would help with a lot of
problems in the same class, so hopefully it will be of some use.

                                    -- Adam



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25  0:42 ` Adam Beneschan
@ 2012-01-25  0:46   ` Adam Beneschan
  2012-01-25  7:38   ` J-P. Rosen
  1 sibling, 0 replies; 19+ messages in thread
From: Adam Beneschan @ 2012-01-25  0:46 UTC (permalink / raw)


On Jan 24, 4:42 pm, Adam Beneschan <a...@irvine.com> wrote:

> A better idea (in my opinion) is to set things up so that the client
> will *call* an entry, rather than accept an entry, when it's ready to
> wait for the request to be completed.  It can't be an entry in the
> server, though, since there's no construct in Ada to "accept" an entry
> just from one specific task.  In Ada 83, I would have had the server
> create a new, small "helper" task for this purpose; the server would
> create a new task when the request is initiated, and later it would
> tell that task when the request can be completed, and the client would
> wait on that task.  Now, protected types can be used for a similar
> purpose....

OK, I didn't realize it at the time, but this is pretty much the same
thing Dmitry suggested.  Just to give credit where it's due...

                      -- Adam




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25  0:42 ` Adam Beneschan
  2012-01-25  0:46   ` Adam Beneschan
@ 2012-01-25  7:38   ` J-P. Rosen
  1 sibling, 0 replies; 19+ messages in thread
From: J-P. Rosen @ 2012-01-25  7:38 UTC (permalink / raw)


Le 25/01/2012 01:42, Adam Beneschan a �crit :
> A better idea (in my opinion) is to set things up so that the client
> will *call* an entry, rather than accept an entry, when it's ready to
> wait for the request to be completed.  It can't be an entry in the
> server, though, since there's no construct in Ada to "accept" an entry
> just from one specific task. 
In a sense, you can. In the first rendezvous, provide to the client an
index into an entry family used to retrieve the data. Excerpt from the
client side:

Server.Send_Data (Data, Inx);
-- do something
Server.Retrieve_Data(Inx)(Data);

-- 
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-24 18:43     ` Dmitry A. Kazakov
@ 2012-01-25 12:43       ` Ada BRL
  2012-01-25 13:48         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 19+ messages in thread
From: Ada BRL @ 2012-01-25 12:43 UTC (permalink / raw)


On 24 Gen, 18:43, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Tue, 24 Jan 2012 09:12:03 -0800 (PST), Ada BRL wrote:
> > On 23 Gen, 19:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> >> On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:
> >>> I've N clients and one server that communicate each other.
> >>> The N clients retrieve data dynamically, send it to the server throgh
> >>> enrty call (obviously the server can accept just one call per time)
> >>> and wait for the reply from the server (through accept statement).
>
> >> A server cannot wait for itself either "through accept statement" or any
> >> other way.
>
> >>    T4.Send_Data (Data);
> >>    accept Retrieve_Data (Data);
>
> >> is a patented way to run into a deadlock.
>
> > yes...you are right ... sorry ... =( BUT I MADE A MISTAKE!!!
>
> > There are two tasks for every communication channel:
> > - one performing input, so retrieving data from the net and sending it
> > to the server (call it T1_IN, T2_IN, ...)
> > - one performing output, so retrieving data from the server and
> > sending it on the net (call it T1_OUT, T2_OUT, ...)
>
> OK. When you are working with sockets you normally do not need a dedicated
> output task. The network stack is already buffered and most likely
> asynchronous to the sender once you have initiated send. Thus you could
> consider sending data straight out of the server.

So, please tell me if I'm right, the server has to implement inside
itself the N output socket connections and I just need to have N tasks
implementing a socket connection each useful just for reading data
from the net and forwarding it to the server?

 Note also that unless you
> have a relatively small number of sockets to handle (a dozen or so), a task
> per socket doing blocking read would not scale.

Are you referring to the tasks reading from the net?


Tasks are used to read
> sockets simply because it is easier to program this way. If you have 2-3
> sockets, why bother with asynchronous socket I/O?

So I don't have to use tasks neither for reading? Sorry but I haven't
got the concept...

But you won't likely get
> a better performance in terms of data throughout and latencies with
> separate reader/writer tasks. Having one server engaging rendezvous with
> writers that would make this design even less reasonable. That is because
> you have the jobs *serialized* in the server. Writers will be either idle
> most of the time waiting for the server or else block server, which would
> want to make a rendezvous with a *concrete* writer each time. You would
> gain nothing from parallelism here, because serialization of processing is
> enforced by server, it only appears parallel. Unless there is some
> considerable post-processing in the writers, it would rather eat
> performance on meaningless task switching.

The writers just receive data from the server and send it over the
net... now I recognize it's not a well designed software... :-(...

Just to see if I have understood everything:

- NO "writers tasks",
- N "readers tasks": every task has just one connection (socket) to
the peer from which receives data,
- Server is connected (by sockets) to N clients to which sends data
after elaboration,
- Server has one entry like: entry Receive_Data(Id_Reader_task : in
Integer; Data : in String), and inside its infinite loop accept this
entry,
- the generic "reader task" i calls the entry of the server like:
Server.Receive_Data(i, data);

Thank you very much!
You have "opened my eyes"!

>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25 12:43       ` Ada BRL
@ 2012-01-25 13:48         ` Dmitry A. Kazakov
  2012-01-25 15:05           ` Ada BRL
  2012-01-26  4:17           ` Randy Brukardt
  0 siblings, 2 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-25 13:48 UTC (permalink / raw)


On Wed, 25 Jan 2012 04:43:57 -0800 (PST), Ada BRL wrote:

> On 24 Gen, 18:43, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> wrote:
>> On Tue, 24 Jan 2012 09:12:03 -0800 (PST), Ada BRL wrote:
>>> On 23 Gen, 19:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
>>> wrote:
>>>> On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:
>>>>> I've N clients and one server that communicate each other.
>>>>> The N clients retrieve data dynamically, send it to the server throgh
>>>>> enrty call (obviously the server can accept just one call per time)
>>>>> and wait for the reply from the server (through accept statement).
>>
>>>> A server cannot wait for itself either "through accept statement" or any
>>>> other way.
>>
>>>> � �T4.Send_Data (Data);
>>>> � �accept Retrieve_Data (Data);
>>
>>>> is a patented way to run into a deadlock.
>>
>>> yes...you are right ... sorry ... =( BUT I MADE A MISTAKE!!!
>>
>>> There are two tasks for every communication channel:
>>> - one performing input, so retrieving data from the net and sending it
>>> to the server (call it T1_IN, T2_IN, ...)
>>> - one performing output, so retrieving data from the server and
>>> sending it on the net (call it T1_OUT, T2_OUT, ...)
>>
>> OK. When you are working with sockets you normally do not need a dedicated
>> output task. The network stack is already buffered and most likely
>> asynchronous to the sender once you have initiated send. Thus you could
>> consider sending data straight out of the server.
> 
> So, please tell me if I'm right, the server has to implement inside
> itself the N output socket connections and I just need to have N tasks
> implementing a socket connection each useful just for reading data
> from the net and forwarding it to the server?

Useful basically for being blocked when there is no data to read from the
socket (actually no data in the network buffer).

>> Note also that unless you
>> have a relatively small number of sockets to handle (a dozen or so), a task
>> per socket doing blocking read would not scale.
> 
> Are you referring to the tasks reading from the net?

Yes. There is a limit on the number of threads a process is allowed to
have. It is not very big, 200 or so under Windows. If you needed to deal
with 1000 connections, it would not help to be able to have 2000 threads,
because switching them will consume too much resources.

>> Tasks are used to read
>> sockets simply because it is easier to program this way. If you have 2-3
>> sockets, why bother with asynchronous socket I/O?
> 
> So I don't have to use tasks neither for reading? Sorry but I haven't
> got the concept...

One task may service several sockets simultaneously. Normally the OS
handles sockets asynchronously to the task reading or writing it, anyway.
So it brings nothing to have more than just one task (I don't consider
multiple network ports here). The task gets notified when the state of a
socket changes. It looks into that socket, takes, for example, the data
already read to this time, processes them and go back to sleep. For more
information see, for example:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx

> Just to see if I have understood everything:
> 
> - NO "writers tasks",
> - N "readers tasks": every task has just one connection (socket) to
> the peer from which receives data,
> - Server is connected (by sockets) to N clients to which sends data
> after elaboration,
> - Server has one entry like: entry Receive_Data(Id_Reader_task : in
> Integer; Data : in String), and inside its infinite loop accept this
> entry,
> - the generic "reader task" i calls the entry of the server like:
> Server.Receive_Data(i, data);

You could consider protected objects, as others already suggested. The
reader might simply queue the packet read and continue, rather than waiting
for a rendezvous with it.

Usually, there are higher level protocol superimposed on the socket stream.
It is a good idea to handle that in the reader and queue "digested"
requests of higher level semantics to the server.

Note one important advantage of having a queue of requests rather than
communicating directly to the server. The queue decouples the readers from
the server. So you could have two or three servers processing the requests
from the queue. On a multi-core architecture that could give you better
throughout. The number of servers can be adjusted later, you need not to
decide it upfront as you would with direct rendezvous.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25 13:48         ` Dmitry A. Kazakov
@ 2012-01-25 15:05           ` Ada BRL
  2012-01-25 18:10             ` Dmitry A. Kazakov
  2012-01-26  4:17           ` Randy Brukardt
  1 sibling, 1 reply; 19+ messages in thread
From: Ada BRL @ 2012-01-25 15:05 UTC (permalink / raw)


On 25 Gen, 13:48, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 25 Jan 2012 04:43:57 -0800 (PST), Ada BRL wrote:
> > On 24 Gen, 18:43, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> > wrote:
> >> On Tue, 24 Jan 2012 09:12:03 -0800 (PST), Ada BRL wrote:
> >>> On 23 Gen, 19:59, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
> >>> wrote:
> >>>> On Mon, 23 Jan 2012 11:32:39 -0800 (PST), Ada BRL wrote:
> >>>>> I've N clients and one server that communicate each other.
> >>>>> The N clients retrieve data dynamically, send it to the server throgh
> >>>>> enrty call (obviously the server can accept just one call per time)
> >>>>> and wait for the reply from the server (through accept statement).
>
> >>>> A server cannot wait for itself either "through accept statement" or any
> >>>> other way.
>
> >>>>    T4.Send_Data (Data);
> >>>>    accept Retrieve_Data (Data);
>
> >>>> is a patented way to run into a deadlock.
>
> >>> yes...you are right ... sorry ... =( BUT I MADE A MISTAKE!!!
>
> >>> There are two tasks for every communication channel:
> >>> - one performing input, so retrieving data from the net and sending it
> >>> to the server (call it T1_IN, T2_IN, ...)
> >>> - one performing output, so retrieving data from the server and
> >>> sending it on the net (call it T1_OUT, T2_OUT, ...)
>
> >> OK. When you are working with sockets you normally do not need a dedicated
> >> output task. The network stack is already buffered and most likely
> >> asynchronous to the sender once you have initiated send. Thus you could
> >> consider sending data straight out of the server.
>
> > So, please tell me if I'm right, the server has to implement inside
> > itself the N output socket connections and I just need to have N tasks
> > implementing a socket connection each useful just for reading data
> > from the net and forwarding it to the server?
>
> Useful basically for being blocked when there is no data to read from the
> socket (actually no data in the network buffer).
>
> >> Note also that unless you
> >> have a relatively small number of sockets to handle (a dozen or so), a task
> >> per socket doing blocking read would not scale.
>
> > Are you referring to the tasks reading from the net?
>
> Yes. There is a limit on the number of threads a process is allowed to
> have. It is not very big, 200 or so under Windows. If you needed to deal
> with 1000 connections, it would not help to be able to have 2000 threads,
> because switching them will consume too much resources.
>

Luckily I don't have thousands of tasks, I can have at about 8 - 10
"readers" from net.

> >> Tasks are used to read
> >> sockets simply because it is easier to program this way. If you have 2-3
> >> sockets, why bother with asynchronous socket I/O?
>
> > So I don't have to use tasks neither for reading? Sorry but I haven't
> > got the concept...
>
> One task may service several sockets simultaneously. Normally the OS
> handles sockets asynchronously to the task reading or writing it, anyway.
> So it brings nothing to have more than just one task (I don't consider
> multiple network ports here). The task gets notified when the state of a
> socket changes. It looks into that socket, takes, for example, the data
> already read to this time, processes them and go back to sleep. For more
> information see, for example:
>
> http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=...

Just a question:
If I have understood well, I may have just one thread connected with N
clients through N sockets, using the SAME PORT.

How may I know if one client (say number 5) is connected or not? I
need an array of connections and so on...
In the case of N readers I can know it, because there's a mapping one-
to-one.

In the case unique reader with N sockets, the OS (in my case MS
Windows 7 Pro) handles the concurrent requests of sending data to the
reader queueing them and delivering each request per time to the
(unique) reader.
For this reason I must trust the fairness / reliability of the OS.

I MUST BE SURE that the data is delivered to the server...what do you
suggest me to do? Multiple readers or only one?

>
> > Just to see if I have understood everything:
>
> > - NO "writers tasks",
> > - N "readers tasks": every task has just one connection (socket) to
> > the peer from which receives data,
> > - Server is connected (by sockets) to N clients to which sends data
> > after elaboration,
> > - Server has one entry like: entry Receive_Data(Id_Reader_task : in
> > Integer; Data : in String), and inside its infinite loop accept this
> > entry,
> > - the generic "reader task" i calls the entry of the server like:
> > Server.Receive_Data(i, data);
>
> You could consider protected objects, as others already suggested. The
> reader might simply queue the packet read and continue, rather than waiting
> for a rendezvous with it.

Regardless to the unique reader / N readers, I have to use a protected
object that incapsulates a buffer (implemented by an array of strings
type);
the reader(s) write into this protected buffer and the server reads
from it.
Am I right? Protected objects implements mutual exclusion by
construction.


>
> Usually, there are higher level protocol superimposed on the socket stream.
> It is a good idea to handle that in the reader and queue "digested"
> requests of higher level semantics to the server.

Yes, this is my case since I have to make some elaboration of incoming
data, and I prefer to forward to the server "digested" data rather
than raw one.


>
> Note one important advantage of having a queue of requests rather than
> communicating directly to the server. The queue decouples the readers from
> the server. So you could have two or three servers processing the requests
> from the queue. On a multi-core architecture that could give you better
> throughout. The number of servers can be adjusted later, you need not to
> decide it upfront as you would with direct rendezvous.

Yes, it's clear :-).

>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25 15:05           ` Ada BRL
@ 2012-01-25 18:10             ` Dmitry A. Kazakov
  2012-01-26 15:19               ` Ada BRL
  0 siblings, 1 reply; 19+ messages in thread
From: Dmitry A. Kazakov @ 2012-01-25 18:10 UTC (permalink / raw)


On Wed, 25 Jan 2012 07:05:57 -0800 (PST), Ada BRL wrote:

> Just a question:
> If I have understood well, I may have just one thread connected with N
> clients through N sockets, using the SAME PORT.

As well as from different Ethernet ports. Reading from one port using
multiple tasks is unlikely to give any performance advantage. But if you
have, for example a 4-port Ethernet controller, you might wish to assign a
separate task for each port.

> How may I know if one client (say number 5) is connected or not? I
> need an array of connections and so on...

Each connection has a socket. Connected/not is a state of a TCP/IP socket.

> In the case of N readers I can know it, because there's a mapping one-
> to-one.
> 
> In the case unique reader with N sockets, the OS (in my case MS
> Windows 7 Pro) handles the concurrent requests of sending data to the
> reader queueing them and delivering each request per time to the
> (unique) reader.

Select() returns list of sockets available to read without blocking. You go
through the list reading the data and pushing them further. Typically, you
have a state machine associated with each input socket. The machine is fed
by the input: often, just one octet, because you don't want to get blocked
due to a protocol error. The state machine swallows the octet and depending
on its internal state and the octet performs a transition accumulating data
as necessary. At some point it queues a request to the server.

> I MUST BE SURE that the data is delivered to the server...what do you
> suggest me to do? Multiple readers or only one?

Delivery is guaranteed (for TCP) and not guaranteed (UDP) independently on
the way of reading. Multiple readers is simpler to implement, so you should
try this first if the number of sockets is bearable.

>> You could consider protected objects, as others already suggested. The
>> reader might simply queue the packet read and continue, rather than waiting
>> for a rendezvous with it.
> 
> Regardless to the unique reader / N readers, I have to use a protected
> object that incapsulates a buffer (implemented by an array of strings type);

When readers perform some preprocessing, then elements of the buffer
(queue) should likely be something more advanced than mere strings.

> the reader(s) write into this protected buffer and the server reads from it.
> Am I right? Protected objects implements mutual exclusion by
> construction.

Yes, it is called "protected action." Waitable operations are entries, like
in the case of tasks. Instant operations are procedures. Functions access
the object in a way that guaranties coherence.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25 13:48         ` Dmitry A. Kazakov
  2012-01-25 15:05           ` Ada BRL
@ 2012-01-26  4:17           ` Randy Brukardt
  1 sibling, 0 replies; 19+ messages in thread
From: Randy Brukardt @ 2012-01-26  4:17 UTC (permalink / raw)


"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message 
news:1rp216zwnjx3j$.rjwu8m3hxgp1.dlg@40tude.net...
...
> Note one important advantage of having a queue of requests rather than
> communicating directly to the server. The queue decouples the readers from
> the server. So you could have two or three servers processing the requests
> from the queue. On a multi-core architecture that could give you better
> throughout. The number of servers can be adjusted later, you need not to
> decide it upfront as you would with direct rendezvous.

Right. My spam filter is structured this way. There is a pool of tasks for 
processing connections, and a manager task that initially receives 
connections and assigns them to tasks. If there aren't any tasks available, 
the filter is getting overloaded and the extra connections are just dropped 
(SMTP will retry them in a while if real, and if junk, who cares?). The 
connections are processed, and presuming that the connection is not blocked, 
the incoming mail message is read, a token created for it, and that is 
queued on the filter queue.

There is then a pool of filter tasks, which grab message tokens from the 
queue, filter the message, and determine what to do with it - delete, 
quarantine, or deliver. Delete is obvious, quarantine just involves moving 
the message files to a special place, and in the deliver case the token is 
put on a delivery queue.

And delivery works the same way: there is a pool of delivery tasks, which 
take messages off the delivery queue whose delivery time is current, and 
tries to deliver them. If successful, the message is deleted from the 
server; otherwise it is put back on the delivery queue with a time in the 
future (in order to support retries).

There are a lot more details (like returning non-delivery messages if a 
message has been retried too long), but that it is general outline -- and it 
works great. (All of the mail going to the Ada-Comment mailing list, along 
with many others, goes thru our spam filter - a 100% Ada program.)

                                              Randy.





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: "C - like: THIS" pointer to a task type inside a task function
  2012-01-25 18:10             ` Dmitry A. Kazakov
@ 2012-01-26 15:19               ` Ada BRL
  0 siblings, 0 replies; 19+ messages in thread
From: Ada BRL @ 2012-01-26 15:19 UTC (permalink / raw)


On 25 Gen, 18:10, "Dmitry A. Kazakov" <mail...@dmitry-kazakov.de>
wrote:
> On Wed, 25 Jan 2012 07:05:57 -0800 (PST), Ada BRL wrote:
> > Just a question:
> > If I have understood well, I may have just one thread connected with N
> > clients through N sockets, using the SAME PORT.
>
> As well as from different Ethernet ports. Reading from one port using
> multiple tasks is unlikely to give any performance advantage. But if you
> have, for example a 4-port Ethernet controller, you might wish to assign a
> separate task for each port.
>
> > How may I know if one client (say number 5) is connected or not? I
> > need an array of connections and so on...
>
> Each connection has a socket. Connected/not is a state of a TCP/IP socket.
>
> > In the case of N readers I can know it, because there's a mapping one-
> > to-one.
>
> > In the case unique reader with N sockets, the OS (in my case MS
> > Windows 7 Pro) handles the concurrent requests of sending data to the
> > reader queueing them and delivering each request per time to the
> > (unique) reader.
>
> Select() returns list of sockets available to read without blocking. You go
> through the list reading the data and pushing them further. Typically, you
> have a state machine associated with each input socket. The machine is fed
> by the input: often, just one octet, because you don't want to get blocked
> due to a protocol error. The state machine swallows the octet and depending
> on its internal state and the octet performs a transition accumulating data
> as necessary. At some point it queues a request to the server.
>
> > I MUST BE SURE that the data is delivered to the server...what do you
> > suggest me to do? Multiple readers or only one?
>
> Delivery is guaranteed (for TCP) and not guaranteed (UDP) independently on
> the way of reading. Multiple readers is simpler to implement, so you should
> try this first if the number of sockets is bearable.
>
> >> You could consider protected objects, as others already suggested. The
> >> reader might simply queue the packet read and continue, rather than waiting
> >> for a rendezvous with it.
>
> > Regardless to the unique reader / N readers, I have to use a protected
> > object that incapsulates a buffer (implemented by an array of strings type);
>
> When readers perform some preprocessing, then elements of the buffer
> (queue) should likely be something more advanced than mere strings.
>
> > the reader(s) write into this protected buffer and the server reads from it.
> > Am I right? Protected objects implements mutual exclusion by
> > construction.
>
> Yes, it is called "protected action." Waitable operations are entries, like
> in the case of tasks. Instant operations are procedures. Functions access
> the object in a way that guaranties coherence.
>
> --
> Regards,
> Dmitry A. Kazakovhttp://www.dmitry-kazakov.de

Thank you.

Just to sum it up:

The best soultion is to have:
- one reader task connected by sockets on N different ports to N
clients,
- one protected object "buffer" that receives data from the reader and
is read by the server,
- one server task that processes data read from the buffer and sends
data back directly to the client.

The second best solution is to have N reader tasks, each with just one
connection to a client (the number of clients is fixed) on a different
port.

I know that using just one port may result in a bottleneck.

Please tell me if I am right,
thanks a lot!



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2012-01-26 15:19 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-01-23 19:32 "C - like: THIS" pointer to a task type inside a task function Ada BRL
2012-01-23 19:59 ` Dmitry A. Kazakov
2012-01-23 22:17   ` tmoran
2012-01-24  8:47     ` Dmitry A. Kazakov
2012-01-24 17:12   ` Ada BRL
2012-01-24 18:43     ` Dmitry A. Kazakov
2012-01-25 12:43       ` Ada BRL
2012-01-25 13:48         ` Dmitry A. Kazakov
2012-01-25 15:05           ` Ada BRL
2012-01-25 18:10             ` Dmitry A. Kazakov
2012-01-26 15:19               ` Ada BRL
2012-01-26  4:17           ` Randy Brukardt
2012-01-24 17:27   ` Ada BRL
2012-01-23 20:20 ` Jeffrey Carter
2012-01-24 17:13   ` Ada BRL
2012-01-24  6:39 ` J-P. Rosen
2012-01-25  0:42 ` Adam Beneschan
2012-01-25  0:46   ` Adam Beneschan
2012-01-25  7:38   ` J-P. Rosen

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