comp.lang.ada
 help / color / mirror / Atom feed
* Ada and (SIGTERM?)
@ 2009-08-05 19:58 Tomek Walkuski
  2009-08-06  1:06 ` Adam Beneschan
  0 siblings, 1 reply; 13+ messages in thread
From: Tomek Walkuski @ 2009-08-05 19:58 UTC (permalink / raw)


Consider program with infinite loop, it simply acts as a server.

How to kill it gracefully with housekeeping (finalization etc)?



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

* Re: Ada and (SIGTERM?)
  2009-08-05 19:58 Ada and (SIGTERM?) Tomek Walkuski
@ 2009-08-06  1:06 ` Adam Beneschan
  2009-08-06 18:13   ` sjw
  2009-08-06 19:30   ` Tomek Wałkuski
  0 siblings, 2 replies; 13+ messages in thread
From: Adam Beneschan @ 2009-08-06  1:06 UTC (permalink / raw)


On Aug 5, 12:58 pm, Tomek Walkuski <tomek.walku...@gmail.com> wrote:
> Consider program with infinite loop, it simply acts as a server.
>
> How to kill it gracefully with housekeeping (finalization etc)?

I suppose "gracefully" precludes pulling the computer's plug out of
the wall?

If I understand, by the subject line, that this program is running on
some Unix-like system and you'd like the program to respond to a
signal and terminate gracefully: did you look at RM C.3?  It seems to
me you could set up an interrupt handler to catch SIGTERM and have it
set a global Boolean variable (make sure to use the Volatile pragma on
the variable), then instead of an "infinite" loop, make the loop
"while not Terminate loop" ... where Terminate is the global variable
that gets set by the interrupt handler.  The details depend on your
Ada implementation.  But that's one simple way to accomplish it.  No
doubt there are other ways, and probably better ones (e.g. the
interrupt handler, which must be a procedure in a protected object,
could set a Boolean in the protected object that controls a protected
entry in the object that could be used in a "select" statement, or
something like that).  In any case, C.3 is the place to start.

                                   -- Adam



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

* Re: Ada and (SIGTERM?)
  2009-08-06  1:06 ` Adam Beneschan
@ 2009-08-06 18:13   ` sjw
  2009-08-06 18:48     ` Adam Beneschan
  2009-08-06 19:30   ` Tomek Wałkuski
  1 sibling, 1 reply; 13+ messages in thread
From: sjw @ 2009-08-06 18:13 UTC (permalink / raw)


On Aug 6, 2:06 am, Adam Beneschan <a...@irvine.com> wrote:

>                    then instead of an "infinite" loop, make the loop
> "while not Terminate loop" ... where Terminate is the global variable
> that gets set by the interrupt handler.  The details depend on your
> Ada implementation.

Most implementations would prefer you to call the variable something
like Quit :-)



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

* Re: Ada and (SIGTERM?)
  2009-08-06 18:13   ` sjw
@ 2009-08-06 18:48     ` Adam Beneschan
  0 siblings, 0 replies; 13+ messages in thread
From: Adam Beneschan @ 2009-08-06 18:48 UTC (permalink / raw)


On Aug 6, 11:13 am, sjw <simon.j.wri...@mac.com> wrote:
> On Aug 6, 2:06 am, Adam Beneschan <a...@irvine.com> wrote:
>
> >                    then instead of an "infinite" loop, make the loop
> > "while not Terminate loop" ... where Terminate is the global variable
> > that gets set by the interrupt handler.  The details depend on your
> > Ada implementation.
>
> Most implementations would prefer you to call the variable something
> like Quit :-)

Yep, "terminate" is a reserved word... forgot about that.

                                 -- Adam




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

* Re: Ada and (SIGTERM?)
  2009-08-06  1:06 ` Adam Beneschan
  2009-08-06 18:13   ` sjw
@ 2009-08-06 19:30   ` Tomek Wałkuski
  2009-08-06 19:57     ` Jeffrey R. Carter
                       ` (2 more replies)
  1 sibling, 3 replies; 13+ messages in thread
From: Tomek Wałkuski @ 2009-08-06 19:30 UTC (permalink / raw)


Thx for replies, but... what am I doing wrong?

protected type Interrupt_Handler is
   procedure Handler;
   pragma Attach_Handler (Handler, 15); -- is it correct for SIGTERM?

   function Quit return Boolean;
private
   Q : Boolean := False;
end Interrupt_Handler;

protected body Interrupt_Handler is
   procedure Handler is
   begin
      Q := True;
   end Handler;

   function Quit return Boolean is
   begin
      return Q;
   end Quit;
end Interrupt_Handler;

Then... somewhere Interrupt_Handler is declared and loop looks like:

while not Quit loop
   Do_Something;
end loop;

And... This does not work. What am I missing?



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

* Re: Ada and (SIGTERM?)
  2009-08-06 19:30   ` Tomek Wałkuski
@ 2009-08-06 19:57     ` Jeffrey R. Carter
  2009-08-06 20:02       ` Tomek Wałkuski
  2009-08-06 20:00     ` okellogg
  2009-08-08 13:11     ` Tomek Wałkuski
  2 siblings, 1 reply; 13+ messages in thread
From: Jeffrey R. Carter @ 2009-08-06 19:57 UTC (permalink / raw)


Tomek Wałkuski wrote:
> Thx for replies, but... what am I doing wrong?
> 
> protected type Interrupt_Handler is
>    procedure Handler;
>    pragma Attach_Handler (Handler, 15); -- is it correct for SIGTERM?

You probably only want a single handler for interrupt 15. So either this should 
be an object rather than a type, or it should have a discriminant to indicate 
the interrupt to handle.

Check your vendor's Ada.Interrupts.Names for the interrupts you can handle on 
your system.

> while not Quit loop
>    Do_Something;
> end loop;
> 
> And... This does not work. What am I missing?

Quit is inside an object of type Interrupt_Handler, and so must be referenced 
using dot notation:

<object>.Quit

"Does not work" is rather vague. Saying "gives me a compilation error with the 
message 'xyz'" or "raises Xyz at run time" or "causes my computer to explode" 
would make it easier to help you.

-- 
Jeff Carter
"Blessed are they who convert their neighbors'
oxen, for they shall inhibit their girth."
Monty Python's Life of Brian
83



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

* Re: Ada and (SIGTERM?)
  2009-08-06 19:30   ` Tomek Wałkuski
  2009-08-06 19:57     ` Jeffrey R. Carter
@ 2009-08-06 20:00     ` okellogg
  2009-08-08 13:11     ` Tomek Wałkuski
  2 siblings, 0 replies; 13+ messages in thread
From: okellogg @ 2009-08-06 20:00 UTC (permalink / raw)


On Aug 6, 9:30 pm, Tomek Wałkuski <tomek.walku...@gmail.com> wrote:
> Thx for replies, but... what am I doing wrong?
>
> protected type Interrupt_Handler is
>    procedure Handler;
>    pragma Attach_Handler (Handler, 15); -- is it correct for SIGTERM?

Yes, although using Ada.Interrupts.Names.SIGTERM could be more
readable.

>
>    function Quit return Boolean;
> private
>    Q : Boolean := False;
> end Interrupt_Handler;
>
> protected body Interrupt_Handler is
>    procedure Handler is
>    begin
>       Q := True;
>    end Handler;
>
>    function Quit return Boolean is
>    begin
>       return Q;
>    end Quit;
> end Interrupt_Handler;
>
> Then... somewhere Interrupt_Handler is declared and loop looks like:
>
> while not Quit loop
>    Do_Something;
> end loop;
>
> And... This does not work. What am I missing?

If you are using GNAT then perhaps you need a

   pragma Unreserve_All_Interrupts;

somewhere in a library level spec.

Just shooting from the hip here -

Oliver



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

* Re: Ada and (SIGTERM?)
  2009-08-06 19:57     ` Jeffrey R. Carter
@ 2009-08-06 20:02       ` Tomek Wałkuski
  0 siblings, 0 replies; 13+ messages in thread
From: Tomek Wałkuski @ 2009-08-06 20:02 UTC (permalink / raw)


On 6 Sie, 21:57, "Jeffrey R. Carter" <spam.jrcarter....@spam.acm.org>
wrote:
> "Does not work" is rather vague. Saying "gives me a compilation error with the
> message 'xyz'" or "raises Xyz at run time" or "causes my computer to explode"
> would make it easier to help you.

Solution posted in my previous post is working. I did stupid mistake
and I thought that it was not working.

Sorry for trouble and thank you for help!



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

* Re: Ada and (SIGTERM?)
  2009-08-06 19:30   ` Tomek Wałkuski
  2009-08-06 19:57     ` Jeffrey R. Carter
  2009-08-06 20:00     ` okellogg
@ 2009-08-08 13:11     ` Tomek Wałkuski
  2009-08-08 15:06       ` Maciej Sobczak
  2 siblings, 1 reply; 13+ messages in thread
From: Tomek Wałkuski @ 2009-08-08 13:11 UTC (permalink / raw)


> protected type Interrupt_Handler is
>    procedure Handler;
>    pragma Attach_Handler (Handler, 15); -- is it correct for SIGTERM?
>
>    function Quit return Boolean;
> private
>    Q : Boolean := False;
> end Interrupt_Handler;
>
> protected body Interrupt_Handler is
>    procedure Handler is
>    begin
>       Q := True;
>    end Handler;
>
>    function Quit return Boolean is
>    begin
>       return Q;
>    end Quit;
> end Interrupt_Handler;
>
> Then... somewhere Interrupt_Handler is declared and loop looks like:
>
> while not Quit loop
>    Do_Something;
> end loop;
>
I cannot stop task if Do_Something is Accept_Socket from GNAT.Sockets.

There is a listener which waits for client connections and then
delegates jobs to the worker tasks. I want to stop all tasks and
finalize all objects when SIGTERM is fired.



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

* Re: Ada and (SIGTERM?)
  2009-08-08 13:11     ` Tomek Wałkuski
@ 2009-08-08 15:06       ` Maciej Sobczak
  2009-08-08 17:53         ` Tomek Wałkuski
  0 siblings, 1 reply; 13+ messages in thread
From: Maciej Sobczak @ 2009-08-08 15:06 UTC (permalink / raw)


On 8 Sie, 15:11, Tomek Wałkuski <tomek.walku...@gmail.com> wrote:

> I cannot stop task if Do_Something is Accept_Socket from GNAT.Sockets.
>
> There is a listener which waits for client connections and then
> delegates jobs to the worker tasks. I want to stop all tasks and
> finalize all objects when SIGTERM is fired.

Use non-blocking I/O and a selector to wait for the sockets to become
ready.
You might need to set up a separate pair of sockets (one for writing
and one for reading - a socket-based implementation of a simple pipe)
which you can use to break out of the selector. This solution is very
scalable and can handle any number of listeners and regular sockets in
a single construct.

If you want to preserve the blocking I/O scheme in your program, you
can break out of Accept_Socket by establishing an artificial
connection to the listening socket. Just pretend to be your own client
and knock to your own door. :-)
When the Accept_Socket returns, check the "quit" flag to decide what
to do next. This flag should be set before establishing this
artificial connection to yourself, so that it is already set up when
Accept_Socket returns.

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

* Re: Ada and (SIGTERM?)
  2009-08-08 15:06       ` Maciej Sobczak
@ 2009-08-08 17:53         ` Tomek Wałkuski
  2009-08-16 13:11           ` Tomek Wałkuski
  0 siblings, 1 reply; 13+ messages in thread
From: Tomek Wałkuski @ 2009-08-08 17:53 UTC (permalink / raw)


On 8 Sie, 17:06, Maciej Sobczak <see.my.homep...@gmail.com> wrote:
> If you want to preserve the blocking I/O scheme in your program, you
> can break out of Accept_Socket by establishing an artificial
> connection to the listening socket. Just pretend to be your own client
> and knock to your own door. :-)
> When the Accept_Socket returns, check the "quit" flag to decide what
> to do next. This flag should be set before establishing this
> artificial connection to yourself, so that it is already set up when
> Accept_Socket returns.
>
Done :)

Thx Maciej.



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

* Re: Ada and (SIGTERM?)
  2009-08-08 17:53         ` Tomek Wałkuski
@ 2009-08-16 13:11           ` Tomek Wałkuski
  2009-08-16 15:47             ` Maciej Sobczak
  0 siblings, 1 reply; 13+ messages in thread
From: Tomek Wałkuski @ 2009-08-16 13:11 UTC (permalink / raw)


Ok, another problem. I have followed your suggestions and I have:
- one request manager,
- one request queue,
- one protected object which provides quit possibility,
- some, for this example five, request workers.

And... how to quit all of them? I cannot force all workers and manager
to look at Quit flag in protected object.

If manager is looking at Quit flag it terminates, but worker tasks
wait on request queue entry (Ludovic's example).
If workers are looking at Quit flag (and manager is not) everything
terminates, but I have to fire SIGTERM signal 6 times (when I have 5
workers).

And of course I am breaking Accept_Socket.




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

* Re: Ada and (SIGTERM?)
  2009-08-16 13:11           ` Tomek Wałkuski
@ 2009-08-16 15:47             ` Maciej Sobczak
  0 siblings, 0 replies; 13+ messages in thread
From: Maciej Sobczak @ 2009-08-16 15:47 UTC (permalink / raw)


On 16 Sie, 15:11, Tomek Wałkuski <tomek.walku...@gmail.com> wrote:

> And... how to quit all of them? I cannot force all workers and manager
> to look at Quit flag in protected object.

If you use the queue of work items, a possible strategy is to define a
special value for the work item[*], so-called "poison pill", that will
be recognized by workers and cause them to quit. If you have N workers
(and you better know how many there are), then just push N "poison
pills" into the queue and it's over.

The poison pill strategy can be also used when there is no queue and a
single manager decides who will get the next work item for processing.

[*] if work items are passed around by pointers (access values), then
null value is a good candidate.

> If workers are looking at Quit flag (and manager is not) everything
> terminates, but I have to fire SIGTERM signal 6 times (when I have 5
> workers).

Why? Do you clear the Quit flag when it is read?

--
Maciej Sobczak * www.msobczak.com * www.inspirel.com

Database Access Library for Ada: www.inspirel.com/soci-ada



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

end of thread, other threads:[~2009-08-16 15:47 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-08-05 19:58 Ada and (SIGTERM?) Tomek Walkuski
2009-08-06  1:06 ` Adam Beneschan
2009-08-06 18:13   ` sjw
2009-08-06 18:48     ` Adam Beneschan
2009-08-06 19:30   ` Tomek Wałkuski
2009-08-06 19:57     ` Jeffrey R. Carter
2009-08-06 20:02       ` Tomek Wałkuski
2009-08-06 20:00     ` okellogg
2009-08-08 13:11     ` Tomek Wałkuski
2009-08-08 15:06       ` Maciej Sobczak
2009-08-08 17:53         ` Tomek Wałkuski
2009-08-16 13:11           ` Tomek Wałkuski
2009-08-16 15:47             ` Maciej Sobczak

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