From: Alex R. Mosteo on
Hibou57 (Yannick Duchêne) wrote:

> Hi Jeffrey, nice to meet you again,
>
> On 5 fév, 22:38, "Jeffrey R. Carter" <spam.jrcarter....(a)spam.acm.org>
> wrote:
>> Technically this is a bounded error: Ada.Text_IO.Put* operations are
>> potentially blocking, and should not be called from a protected
>> operation.
> I did not ever suspected such a requirement. Transitive blocking is
> not allowed ?
>
> So, if blocking operation are not allowed from a protected type,
> clients of a given operation have to know it weither or not it's
> potentially blocking, and so, this fact must be stated in public part
> of specifications, so then, the protected and tasked aspect of a
> method must be stated in specifications and I suppose it's not a good
> idea to make it private.

I have had some headaches not long along because of potentially blocking
operations. The short conclusion is that as long as you don't try anything
strange, you'll do well. By strange I mean things that may seem "clever" at
some point like calling a task from a protected or so.

Past versions of gnat where indulging about this, there's now a pragma that
won't allow it and that I recommend to use; you'll save further problems
with deadlocks. I think is pragma Detect_Blocking.

So, if your type is encapsulating a hidden call to a task entry, it would be
advisable to document it in the call, because this indeed can raise an
exception at runtime if called from a protected op. I think this is a
recommendation, but a bounded error in any case. The above pragma enforces
its detection.

However, I don't think it's recommended design to call from protected ops to
foreign, implementation-unknown, subprograms. Protected calls should
encapsulate something as well defined and narrow as possible.

I make extensive use of protected and task types generally without issue; my
problem was that I had to quickly hack a solution for a convoluted tasking
subsystem and I was frankly abusing the design. In general, sticking to the
client-server model for tasks/protected objects covers 99% of use cases and
it's totally safe.

> Wrong or right assumptions ?
>
>> This should not happen. Did you actually experience this?
> No, I did not experience it, this was just my imagination : I knew a
> task may completes at its own discretion. Thus if may possibly
> completes too much soon if its completion condition is not well
> designed.
>
> I will have to check the RM, but I'm pretty sure a completed task
> cannot handle any request any more (at least, this seems to be a
> reasonable assumption to me, but I will still have to check...).

At first I also was reticent of terminate parts, but this is really one of
these nice aspects of Ada where something apparently complex is done for you
by the language :)
From: Jean-Pierre Rosen on
Hibou57 (Yannick Duch�ne) a �crit :

> So, if blocking operation are not allowed from a protected type,
> clients of a given operation have to know it weither or not it's
> potentially blocking, and so, this fact must be stated in public part
> of specifications, so then, the protected and tasked aspect of a
> method must be stated in specifications and I suppose it's not a good
> idea to make it private.
>
> Wrong or right assumptions ?
>
Right. Thats why there is a rule in AdaControl to check potentially
blocking operations called from protected actions.

The check is of course pessimistic (if it were really statically
checkable, it would be forbidden by langage rules). So it checks for
potentially potentially blocking operations ;-)

--
---------------------------------------------------------
J-P. Rosen (rosen(a)adalog.fr)
Visit Adalog's web site at http://www.adalog.fr
From: Maciej Sobczak on
On 5 Lut, 22:53, Hibou57 (Yannick Duchêne) <yannick_duch...(a)yahoo.fr>
wrote:

> I did not ever suspected such a requirement. Transitive blocking is
> not allowed ?

As far as I understand, there is a careful wording around this subject
so that formally speaking protected operations (except for entries)
are not themselves "blocking". So, for example, you can call protected
operations from other protected operations.

The operations that are considered to be blocking in this context are
delay statements, entry calls, select statements and... I/O
operations. These cannot be called from protected operations.

(I'm sure somebody will correct me if I'm off tracks)

> So, if blocking operation are not allowed from a protected type,
> clients of a given operation have to know it weither or not it's
> potentially blocking,

That would be nice, yes. But be careful, this approach might blow up
the language. What about exception specifications? And so on.

But: see RavenSPARK.

The problem with blocking in particular is that there is no way to
verify whether imported subprograms (from C libraries, for example)
are blocking. You can import I/O operations from C libraries and there
is no way to verify what they do.

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

Database Access Library for Ada: www.inspirel.com/soci-ada
From: Dmitry A. Kazakov on
On Mon, 8 Feb 2010 09:28:44 -0800 (PST), Maciej Sobczak wrote:

> The problem with blocking in particular is that there is no way to
> verify whether imported subprograms (from C libraries, for example)
> are blocking. You can import I/O operations from C libraries and there
> is no way to verify what they do.

You do not need that. The default must be "blocking". The programmer
overrides the default if he is sure that the imported subprogram is not
blocking. This is no different to the parameter profile of an imported
procedure. There is no way to verify it. So the programmer just gives his
word, and the compiler rely on it.

--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
From: Hibou57 (Yannick Duchêne) on
On 8 fév, 18:28, Maciej Sobczak <see.my.homep...(a)gmail.com> wrote:
> As far as I understand, there is a careful wording around this subject
> so that formally speaking protected operations (except for entries)
> are not themselves "blocking". So, for example, you can call protected
> operations from other protected operations.
>
> The operations that are considered to be blocking in this context are
> delay statements, entry calls, select statements and... I/O
> operations. These cannot be called from protected operations.
>
> (I'm sure somebody will correct me if I'm off tracks)
Protected types was most the subject of another thread, but as you
talked about it here : I don't understand why you've protected
operation (I suppose you were talking about procedures, not entries)
are not themselves blocking. They grant exclusive read-write access
and ensure there is no race. So if another task is currently running
the procedure of a protected type, another task cannot enter this
procedure if it was to do so and a task switch occurs at the same
time.

Or is it guaranteed that no task switch can occurs when a task is
actually in a procedure of a protected type ? Is the task switch
delayed in such a circumstance ?

Let temporarily suppose so. But remains another wolf in the wood :
what if the application is running in a multiprocessors environment
and its thread are not executed on the same CPU ? If one task on CPU#1
was to enter a procedure of a protected object while a task on CPU#2
is actually running a procedure on the same protected object, then,
the task running on CPU#1 must be delayed, and thus, the procedure is
blocking.

Sure a procedure of a protected type or object should be short and
quick to execute, but it seems to still remains potentially blocking.