shared

shared (along with owned) manage the deallocation of a class instance. shared is meant to be used when many different references will exist to the object and these references need to keep the object alive.

Using shared

To use shared, allocate a class instance following this pattern:

var mySharedObject = new shared MyClass(...));

When mySharedObject and any copies of it go out of scope, the class instance it refers to will be deleted.

Copy initializing or assigning from mySharedObject will make other variables refer to the same class instance. The class instance will be deleted after all of these references go out of scope.

var globalSharedObject:shared MyClass;

proc makeGlobalSharedObject() {
  var mySharedObject = new shared MyClass(...);
  globalSharedObject = mySharedObject;
  // the reference count is decremented when mySharedObject
  // goes out of scope. Since it's not zero after decrementing, the
  // MyClass instance is not deleted until globalSharedObject
  // goes out of scope.
}

Borrowing from shared

The shared.borrow method returns the pointer managed by the shared. This pointer is only valid as long as the shared is storing that pointer. The compiler includes some checking for errors in this case. In these ways, shared is similar to owned.

See Borrowing from owned for more details and examples.

Coercions for shared

As with owned, shared supports coercions to the class type as well as coercions from a shared(T) to shared(U) where T is a subclass of U.

See Coercions for owned for more details and examples.

shared Intents and Instantiation

Intents and instantiation for shared are similar to owned. Namely:

  • for formal arguments declared with a type, the default intent is const in, which updates the reference count and shares the instance.

  • for generic formal arguments with no type component that are passed actuals of shared type, the formal argument will be instantiated with the borrow type, and no reference count changes will occur.

    Note

    It is expected that this rule will change in the future with more experience with this language design.

See also owned Intents and Instantiation which includes examples.

record shared

shared manages the deletion of a class instance in a way that supports multiple owners of the class instance.

This is currently implemented with task-safe reference counting.

proc init(type t)

Default-initialize a shared.

proc init(p: unmanaged)

Initialize a shared with a class instance. This shared will take over the deletion of the class instance. It is an error to directly delete the class instance while it is managed by shared.

Arguments:p -- the class instance to manage. Must be of unmanaged class type.
proc init(p: ?T)
proc init(in take: owned)

Initialize a shared taking a pointer from a owned.

This shared will take over the deletion of the class instance. It is an error to directly delete the class instance while it is managed by shared.

Arguments:take -- the owned value to take ownership from
proc init=(const ref src: shared ?)

Copy-initializer. Creates a new shared that refers to the same class instance as src. These will share responsibility for managing the instance.

proc init=(src: borrowed)
proc init=(src: unmanaged)
proc init=(src: _nilType)
proc deinit()

The deinitializer for shared will destroy the class instance once there are no longer any copies of this shared that refer to it.

proc ref retain(newPtr: unmanaged)

Change the instance managed by this class to newPtr. If this record was the last shared managing a non-nil instance, that instance will be deleted.

proc ref clear()

Empty this shared so that it stores nil. Deletes the managed object if this shared is the last shared managing that object. Does not return a value.

Equivalent to shared.retain(nil).

proc borrow()

Return the object managed by this shared without impacting its lifetime at all. It is an error to use the value returned by this function after the last shared goes out of scope or deletes the contained class instance for another reason, including calls to =, or shared.retain when this is the last shared referring to the instance. In some cases such errors are caught at compile-time.

proc =(ref lhs: shared, rhs: shared)

Assign one shared to another. Deletes the object managed by lhs if there are no other shared referring to it. On return, lhs will refer to the same object as rhs.

proc =(ref lhs: shared, in rhs: owned)

Set a shared from a owned. Deletes the object managed by lhs if there are no other shared referring to it. On return, lhs will refer to the object previously managed by rhs, and rhs will refer to nil.

proc <=>(ref lhs: shared, ref rhs: shared)

Swap two shared objects.

proc _cast(type t: shared class, const ref x: shared nilable class) throws
proc _cast(type t: shared class, const ref x: shared class) throws
proc _cast(type t: shared nilable class, const ref x: shared nilable class)
proc _cast(type t: shared nilable class, const ref x: shared class)