Cω - Reference

Concurrency Constructs

This section gives a nearly-formal specification of the extensions to the C# grammar associated with Cω (Cω) concurrency constructs.

Note  This section is part of the formal specification of the Cω language. It is not intended as a tutorial. For help in learning about how to use the Cω concurrency constructs in your code, see Cω Tutorials.

Asynchronous methods

Asynchronous methods have a return type of async, which is a new keyword in Cω (similar to void).

Each asynchronous method in a class must have an explicit async-declaration of the form

attributesopt method-modifiersopt
async member-name(formal-parameter-listopt); 

Async-declarations can appear in interfaces and one can also declare asynchronous delegate types:

attributesopt delegate-modifiersopt
delegate async identifier(formal-parameter-listopt);

Chords

Chords (or synchronization patterns) define the behaviours of asynchronous methods and of those (ordinary) synchronous methods which synchronize with asynchronous ones. The definition method-declaration in the C# grammar is replaced by the following in Cω:

sync-method-header sync-chord+

where sync-method-header is

attributesopt method-modifiersopt
(void|type) member-name(formal-parameter-listopt) 

and sync-chord is

(& async-header)* method-body

where async-header is

member-name(formal-parameter-listopt)

There are also another form of class-member-declaration in Cω, viz. async-chord, which is defined by

when async-header(&async-header)* method-body

where when is another new keyword.

Well-formedness conditions

This last restriction means that, for example, the following is ill-formed:

public class C {
   virtual async g();
   virtual void f() & g() {
   ...
  }
  ...
}
public class D : C {
  override void f() {
    ...
  }
  ...
}

Since in D, we have overridden the definition of f() in C but have not also overridden g() with which it appears in a chord. (If g() were non-virtual then the definition of C alone would generate a warning, since f() would be declared virtual but could never be legally overridden.)

Typing

We treat async as a subtype of void and allow covariant return types just in the case of these two (pseudo)types. Thus

but not conversely. This design makes intuitive sense (an async method is a void one, but has the extra property of returning `immediately') and also maximizes compatibility with existing C# code (superclasses, interfaces and delegate definitions) making use of void.

Semantics

An asynchronous method will return (essentially) immediately to its caller without blocking and with no result. Asynchronous methods are automatically given the OneWay attribute, so that calls to them over remoting are genuinely non-blocking.

Each chord involves a non-empty set of methods. A chord is enabled on an object (or class, in the case of static chords) when at least one unconsumed call has been made to each of those methods on that object (or class). When an asynchronous method is called on an object (or class) and no chord is thereby enabled, the call is queued. When a synchronous method is called on an object (or class) and no chord is enabled, the calling thread is blocked and queued. When at least one chord is enabled on an object (or class) then (an unspecified) one of them will be chosen to fire, which consumes (dequeues) one (unspecified) call of each of the methods in the chord and executes the body of the chord with the formal parameters bound to the arguments of those calls. In the case of a synchronous chord, the body is executed in the reawoken thread which made the consumed synchronous call. In the case of an asynchronous chord, the body is executed in a new thread.