Skip to content
Haiku OSDeep Dive Published Updated 5 min readViews unavailable

Haiku's BRoster and registrar: How Applications Are Found and Launched

How Haiku tracks running applications, resolves signatures and files, enforces launch modes, sends roster notifications, and returns BMessengers.

Launching a Haiku application is more than creating a process from a pathname. The Application Kit identifies applications by MIME-style signatures, records running instances, enforces single or multiple launch policy, routes files to preferred handlers, and provides message endpoints for inter-application communication.

BRoster is the public interface to that state. Native applications normally use the global be_roster, which is initialized with BApplication and connected to the system registrar service.

Signatures provide identity above a pathname

A native application declares a signature such as application/x-vnd.example-Editor. The signature can be stored as an attribute and resource in the executable. BApplication uses it when connecting to the Application Server and registrar.

The signature lets Haiku ask whether an application is running, find its executable, route a message, or launch the preferred handler for a type without hard-coding /boot/system/apps/.... Moving an app therefore does not have to change every caller.

Signatures are identifiers, not cryptographic identities. Two unrelated binaries should not claim the same signature, and callers must not treat a match as proof of publisher authenticity.

app_info connects the roster to kernel objects

BRoster queries return app_info, which includes the application’s team ID, main thread, message port, launch flags, executable reference, and signature. A Haiku team is the kernel process-like container for threads and resources.

app_info info;
if (be_roster->GetRunningAppInfo(team, &info) == B_OK) {
    // Inspect info.signature, info.ref, info.thread, and info.port.
}

The data is a snapshot. The team can exit immediately after the query and IDs can later be reused. When the next operation is a message, create a BMessenger and handle delivery failure instead of assuming the app_info stays live.

Roster methods can list all application teams, find the active application, map a signature to a team, and retrieve information by team, signature, or entry reference. Use the narrowest lookup for the question and distinguish “not installed” from “installed but not running.”

Launch flags control duplicate instances

Application flags declare one of several launch modes. B_MULTIPLE_LAUNCH permits several instances. B_SINGLE_LAUNCH permits one instance of a particular executable. B_EXCLUSIVE_LAUNCH permits one instance for the signature.

When a second launch targets an application that should remain single, the system can deliver arguments or entry references to the existing instance rather than start another process. The application’s ArgvReceived() and RefsReceived() hooks are therefore part of its launch behavior, not optional command-line decoration.

Choose the mode from data ownership. An editor may support multiple independent processes, while a mail daemon or settings service may need one exclusive owner. Exclusive launch alone does not serialize every internal operation; the app still needs normal thread safety.

Files resolve through MIME handling

BRoster::Launch() can target an application signature, an executable reference, or a document. For a document, Haiku’s MIME database and preferred-application associations determine the handler. The selected app receives an entry_ref rather than requiring the caller to construct a command string.

This avoids shell quoting problems and preserves filesystem identity better than concatenating a pathname. Still, the receiver must validate type and content. A preferred MIME association is user intent, not a promise that the file is well formed.

If several files are launched together, preserve their grouping in one request where the API permits it. Starting the app separately for every file can race with single-launch registration and produce an unexpected order.

Watch the roster instead of polling it

StartWatching() registers a BMessenger for application launch and quit notifications. The messages include roster fields that identify the affected team and signature. StopWatching() removes the subscription.

Watchers should first take an inventory, then consume events, and account for the gap between those actions. If exact state matters, reconcile the roster after installing the watch. A desktop monitor that only listens for future launches misses every app that was already running.

Delivery is asynchronous. The target looper needs to remain alive, parse only documented fields, and tolerate a launch followed immediately by quit. Do not perform slow filesystem inspection directly in the message handler.

The registrar maintains application and MIME-related state exposed through Application Kit APIs. Haiku’s launch_daemon manages system jobs and services, with the launch_roster command inspecting that separate service graph. Similar names do not make BRoster a general service-manager API.

Use BRoster for GUI and native application identity, launch, and observation. Use launch-daemon facilities for configured jobs, dependencies, and services. Mixing the two produces fragile code that happens to find a process but does not own its lifecycle.

Make launch failure part of the protocol

Every roster lookup and launch returns a status_t, and the distinction between errors matters. A missing preferred handler, an invalid signature, an executable that cannot be loaded, and an application that was launched but rejected a message are different states. Preserve the original status code and the target identity in logs instead of reducing all of them to “application did not open.”

For single-launch applications, a successful request may mean that the registrar routed arguments or references to an existing team. The caller should not wait for a new PID as its only proof of success. If a reply is required, include a reply messenger or establish an application-level acknowledgement that names the document or operation. Roster delivery confirms routing, not that the receiver finished the requested work.

Do not keep an app_info structure as a durable session record. Team IDs, thread IDs, and ports describe a live kernel instance and can be reused after exit. Keep the stable signature and file identity for product state, then reacquire a BMessenger and handle an invalid target for each interaction. A long operation should have its own request identifier so reconnecting to a relaunched application cannot accidentally complete an older request twice.

Finally, test the race cases deliberately: launch the app while it is quitting, move the executable between lookup and launch, open several documents concurrently under each launch mode, and restart the registrar-facing application during delivery. Haiku’s roster resolves system identity, but robust software still needs idempotent messages and explicit completion semantics above it.

Haiku’s launch model is cohesive because filesystem metadata, MIME types, kernel teams, message ports, and application signatures meet behind one public interface. Code that respects those identities can launch and communicate without depending on where the user placed an application.

Related:

Sources:

Comments