comp.lang.ada
 help / color / mirror / Atom feed
* Potentially_Blocking aspect
@ 2016-04-28 15:53 mockturtle
  2016-04-28 20:30 ` Randy Brukardt
  2016-04-28 22:07 ` Jeffrey R. Carter
  0 siblings, 2 replies; 4+ messages in thread
From: mockturtle @ 2016-04-28 15:53 UTC (permalink / raw)


Hi.all, 
a curiosity just came to my mind.  

Inside a protected object it is forbidden to invoke a potentially blocking operation.  Although some cases are easily recognized, it could be that a procedure invokes (via several levels of indirection) a blocking action.  As I understand, you can specify pragma Detect_Blocking, but this works at runtime (since H.5 says "An implementation is required to detect a potentially blocking operation within a protected operation, and to raise Program_Error").

I was wondering about a possible Potentially_Blocking aspect.  Something like
(disclaimer: I am making it while I am writing...)

procedure foo(x: integer)
with Potentially_Blocking;

It would be a compile-time error if a procedure that does something blocking (an entry call, a select, ... or a call to another Potentially_Blocking procedure) does not have the Potentially_Blocking aspect.  Likewise, it would be an error to have the aspect when the procedure is not potentially blocking.
This would allow you to detect calls to blocking procedures at compile time.

Of course, in order to avoid back-compatibility problems, you could add a pragma like Mandatory_Potentially_Blocking(Flag : Boolean) that allows you to turn on and off the necessity declaring potentially blocking procedures.

I checked and it seems that no such aspect is currently defined.  There is some special reason for this?

Riccardo


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

* Re: Potentially_Blocking aspect
  2016-04-28 15:53 Potentially_Blocking aspect mockturtle
@ 2016-04-28 20:30 ` Randy Brukardt
  2016-04-28 22:07 ` Jeffrey R. Carter
  1 sibling, 0 replies; 4+ messages in thread
From: Randy Brukardt @ 2016-04-28 20:30 UTC (permalink / raw)


See AI12-0064-1 and AI12-0064-2. That, we're actively working on it. 
(Although the sense is backwards from your idea; but that's obviously 
necessary for compatibility.)

The problem is, neither of those proposals really works for compatiblity and 
usability purposes. (Requiring all existing generics, like the containers, 
to be potentially blocking, defeats the purpose in my mind - which kills 
alternative 1. And my alternative (2) doesn't work because in many real 
cases, the function or object can't be the prefix of an attribute as it 
doesn't have a unique name. "="'Nonblocking just doesn't work in Ada.)

This is obviously a hard problem. I don't know where we'll go from here, but 
I'm sure we'll be discussing these again in Pisa.

                                          Randy.

"mockturtle" <framefritti@gmail.com> wrote in message 
news:84d1b14e-7d8d-4bf4-820b-1fc93ed76114@googlegroups.com...
Hi.all,
a curiosity just came to my mind.

Inside a protected object it is forbidden to invoke a potentially blocking 
operation.  Although some cases are easily recognized, it could be that a 
procedure invokes (via several levels of indirection) a blocking action.  As 
I understand, you can specify pragma Detect_Blocking, but this works at 
runtime (since H.5 says "An implementation is required to detect a 
potentially blocking operation within a protected operation, and to raise 
Program_Error").

I was wondering about a possible Potentially_Blocking aspect.  Something 
like
(disclaimer: I am making it while I am writing...)

procedure foo(x: integer)
with Potentially_Blocking;

It would be a compile-time error if a procedure that does something blocking 
(an entry call, a select, ... or a call to another Potentially_Blocking 
procedure) does not have the Potentially_Blocking aspect.  Likewise, it 
would be an error to have the aspect when the procedure is not potentially 
blocking.
This would allow you to detect calls to blocking procedures at compile time.

Of course, in order to avoid back-compatibility problems, you could add a 
pragma like Mandatory_Potentially_Blocking(Flag : Boolean) that allows you 
to turn on and off the necessity declaring potentially blocking procedures.

I checked and it seems that no such aspect is currently defined.  There is 
some special reason for this?

Riccardo 


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

* Re: Potentially_Blocking aspect
  2016-04-28 15:53 Potentially_Blocking aspect mockturtle
  2016-04-28 20:30 ` Randy Brukardt
@ 2016-04-28 22:07 ` Jeffrey R. Carter
  2016-04-29  7:31   ` Dmitry A. Kazakov
  1 sibling, 1 reply; 4+ messages in thread
From: Jeffrey R. Carter @ 2016-04-28 22:07 UTC (permalink / raw)


On 04/28/2016 08:53 AM, mockturtle wrote:
>
> Inside a protected object it is forbidden to invoke a potentially blocking
> operation.  Although some cases are easily recognized, it could be that a
> procedure invokes (via several levels of indirection) a blocking action.  As
> I understand, you can specify pragma Detect_Blocking, but this works at
> runtime (since H.5 says "An implementation is required to detect a
> potentially blocking operation within a protected operation, and to raise
> Program_Error").

This restriction was a mistake. Protected objects exist to provide mutual 
exclusion without a thread of control. There are plenty of cases where mutual 
exclusion is needed, a thread of control is not, and blocking operations must be 
called. Requiring the use of a task in such cases is unreasonable, but is what 
we have.

Some compilers allow potentially blocking operations in protected operations by 
default, not raising Program_Error even when such an operation is detected, 
unless the user explicitly specifies otherwise. Clearly, people frequently want 
to put such operations into protected operations.

-- 
Jeff Carter
"[T]he Musgroves had had the ill fortune
of a very troublesome, hopeless son, and
the good fortune to lose him before he
reached his twentieth year ..."
Persuasion
154


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

* Re: Potentially_Blocking aspect
  2016-04-28 22:07 ` Jeffrey R. Carter
@ 2016-04-29  7:31   ` Dmitry A. Kazakov
  0 siblings, 0 replies; 4+ messages in thread
From: Dmitry A. Kazakov @ 2016-04-29  7:31 UTC (permalink / raw)


On 29/04/2016 00:07, Jeffrey R. Carter wrote:
> On 04/28/2016 08:53 AM, mockturtle wrote:
>>
>> Inside a protected object it is forbidden to invoke a potentially blocking
>> operation.  Although some cases are easily recognized, it could be that a
>> procedure invokes (via several levels of indirection) a blocking action. As
>> I understand, you can specify pragma Detect_Blocking, but this works at
>> runtime (since H.5 says "An implementation is required to detect a
>> potentially blocking operation within a protected operation, and to raise
>> Program_Error").
>
> This restriction was a mistake. Protected objects exist to provide
> mutual exclusion without a thread of control.

That is too broad and too narrow. What protected object actually do is 
atomic access to the object's data and synchronization through the entry 
queues.

> There are plenty of cases
> where mutual exclusion is needed, a thread of control is not, and
> blocking operations must be called.

Yes, but that is not a job for an atomic operation, which projected 
object models. An atomic operation is logically instant. A blocking 
operation neither logically nor physically is.

> Requiring the use of a task in such
> cases is unreasonable, but is what we have.

A mutex can be easily implemented using protected objects. And nothing 
precludes Ada designers from introducing an "exclusive" interface or 
aspect (new Ada's darling). For example:

type Task_Unsafe is tagged ...;
procedure Foo (X : in out Task_Unsafe);

type Task_Safe is exclusive new Task_Unsafe with null record;

This translates into:

type Task_Safe is new Task_Unsafe with record
    Mutex : Mutex_Type;
end record;

and overrides all primitive operations of the parent type this way:

procedure Foo (X : in out Task_Safe) is
begin
    X.Mutex.Seize;
    Foo (Task_Unsafe (X));
    X.Mutex.Release;
exceptions
    when others =>
       X.Mutex.Release;
       raise;
end Foo;

[ It would be nice if Ada provided more generic means for delegation 
allowing user-defined wrappers added like above. ]

> Some compilers allow potentially blocking operations in protected
> operations by default, not raising Program_Error even when such an
> operation is detected, unless the user explicitly specifies otherwise.

Yes, but don't let that slip into production code. Text_IO.Put_Line 
inside a protected action is meant for debugging only.

And conversion bugs into run-time errors is a bad idea in general. 
Clearly no run-time check should be made, it is the same wrong of all 
dynamic constraint and accessibility checks.

> Clearly, people frequently want to put such operations into protected
> operations.

And the compiler should prevent them doings this, as much as it can.

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


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

end of thread, other threads:[~2016-04-29  7:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-04-28 15:53 Potentially_Blocking aspect mockturtle
2016-04-28 20:30 ` Randy Brukardt
2016-04-28 22:07 ` Jeffrey R. Carter
2016-04-29  7:31   ` Dmitry A. Kazakov

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