// then, before the write takes place, copy the object.
// It is undefined whether this mapping will receive
// the copy or the original.
-
+
+ Snapshot, // The mapped object will also be made CopyOnWrite, so
+ // that any writes to the mapped page via any mapping
+ // will cause a fault. Thus, after the snapshot, the
+ // only changes that will be visible will be through
+ // the new mapping. This is ideal for things like fork()
+ // and file versioning, and is used by AddrSpace.clone().
+ //
+ // If not set, then only the new mapping will be
+ // CopyOnWrite, so if another mapping updates the page
+ // before a write occurs through this mapping (thus
+ // breaking CopyOnWrite), the change will be visible in
+ // the new mapping. This is ideal for private
+ // mappings, where all that is desired is that the new
+ // mapping cannot change the underlying object (while
+ // keeping the mapping writeable).
+ //
+ // Ignored if CopyOnWrite is not set.
+
AccessFlags access:3,
// These are the requested read/write/execute
// permissions on the mapping. A missing permission (or
// By default, the old address space continues to be backed by
// whatever Mappables were in use, and pages in the new address space
// are backed by anonymous memory when a page in either is written to.
- // If old_space_is_anon is true, though, this is reversed, which is useful
+ // If flags.Reverse is true, though, this is reversed, which is useful
// when versioning a file to make the new version the one that gets
// stored to disk.
+ //
+ // The upstream address space is also marked as copy-on
- clone(AddrSpace addrspace out, bool clone_is_real);
+ clone(AddrSpace addrspace out, CloneFlags flags);
+
+ bitfield CloneFlags {
+ Reverse
+ };
// Mappable must be implemented by the local kernel, and must hold
// read/write/exec permissions appropriate for the MapFlags given.
DatumDesc[] data;
};
- interface Class {
- guid: "C30D0A85-EA8B-11D9-B985-000A95BB581A";
- query_interface(Interface iface, bool supported out);
- instantiate(Object instance out);
- };
-
- interface Interface {
- guid: "C36EBE18-EA8B-11D9-896D-000A95BB581A";
- };
-
- interface Method {
- guid: "C3D1BA69-EA8B-11D9-9439-000A95BB581A";
- };
-
- interface Struct {
- guid: "C4384909-EA8B-11D9-B856-000A95BB581A";
- };
-
- interface Filter {
- guid: "C4A89048-EA8B-11D9-BB2C-000A95BB581A";
+ interface IDSpace {
+ guid: "06489629-9C25-4C14-9A5B-6C59639C87D6";
- // Returns the object from which the filter was created.
- // This will only succeed if the calling process already
- // has a reference to the real object. If the filter
- // points to another filter, it will return the transitive
- // real object if possible, or else the filter closest to
- // the real object for which the process already has a
- // reference. If neither the real object nor a closer
- // filter can be returned, this filter itself is returned.
- // This should not be used for comparing filter references,
- // as separately created filters for the same object will
- // have different IDs and pointers, even if they contain
- // the same subset of interfaces.
+ new_object(Mem.AddrSpace aspace, ulong entry, ID obj out);
- get_real_obj(Object obj out);
-
- // Returns a local ID of the real object, regardless of whether
- // the calling process has a reference to it, or whether there
- // are other intervening filters. The ID cannot be used to
- // invoke methods, but it can be used to compare the identities
- // of the objects behind different filter objects. If a real
- // reference to the object is later obtained, it will have
- // the same local ID.
-
- get_real_obj_id(ID id out);
- };
-
- interface ObjectManager {
- guid: "C28596AB-EA8B-11D9-8DEB-000A95BB581A";
-
- new_object(ID cla, ID obj out);
- delete_object(ID obj) async;
-
- new_interface(ID cd, ID cla out);
- delete_interface(ID cla, bool call_del) async;
-
- open_object(ID obj, uint handle out);
- close_object(uint handle) async;
-
- // Create a filter object that implements only some of the
- // interfaces implemented by "obj". This is useful to create a
- // more limited reference to pass to less trusted processes. If
- // "exclude" is true, then all interfaces but those specified will
- // be included. Otherwise, only those interfaces specified will be
- // included. A filter with no interfaces may be created to act as
- // a (mostly) opaque handle.
+ // Release "num" references on the object. If exactly "num"
+ // references remain, the object handle is closed and "gone" is
+ // true. If more references remain, the handle is not closed and
+ // "gone" is false. If fewer references than "num" are present
+ // when called, no references are released, and RefCountException
+ // is thrown.
//
- // A holder of a filter reference can convert it into the real
- // object if it already has (or later obtains) a reference to to
- // the real object. It can also compare the identities of
- // separately created filters pointing at the same object
- // regardless of what it has a real reference to. Thus, filters
- // should be used only to limit access granted by passing a
- // reference to another process; it should not be used to hide the
- // identity of the real object.
+ // A handle's refcount is incremented whenever a reference is
+ // received via IPC. Objects created with new_object start with
+ // a refcount of 1.
- create_filter(Object obj, bool exclude, Interface[] ifaces,
- Filter filter out);
+ release(ID obj, int num, bool gone out);
};
// This is a generic Factory interface; specific factories may