Modularity within RISC OS

Introduction

RISC OS has, from the outset, been designed to be modular in nature. This modularity brings many advantages, not least of which is the replaceability of components. It is highly desirable that components be able to handle being replaced whilst the system is in use. Whilst this has obvious developmental advantages, it also aids in upgrading components should a major failure be found.

It is usual for replacement components to be loaded during the system start up. Toolbox is a typical example which will be loaded during the boot sequence to replace the default versions in ROM. As a rapidly evolving library, Toolbox is regularly replaced.

Where possible it is desirable that the system not require any restart in order to ensure that components be loaded correctly. Although, for development purposes, clean environments are preferable, it is frustrating for users to be prompted to restart the system.

Services for replacement modules

In order that modules be able to handle replacement in a structured manner it is important that they correctly register with their dependencies, and re-register themselves when those dependencies are restarted. Examples of the services which must be monitored by various clients:

Many other examples exist at various levels, both as part of RISC OS and as 3rd party extensions. Components should use the most suitable mechanism for the purpose to ensure that the system continues to function.

Alternative services

As an alternative to registering unique services just for module start up and death, the service Service_ModuleStatus may be used to identify named modules starting, dying and being reinstantiated. This is less ideal because it does not allow for different modules to be used in place of the named modules (for example a Sound controller with a different name to SoundDMA). However, this is usually not a major constraint.

Recommendations for modularity

In order to be replaceable 'on the fly', components must:

Modularity and applications

In many cases there is no mechanism to notify applications of state changes within modules. Components may use their own mechanisms for determining the state of their dependency module. Usually this involves the opaque handles returned from modules being validated by some mechanism. This can cause the application to terminate if it is unexpected, or for operations to be cancelled. Component replacement is expected within an active system, but side effects are usually unavoidable. Replacement of, for example, the Internet module will be handled gracefully by most module components, but applications will usually fail in their active operations due to invalid socket errors. Because the module claimants will (usually) obtain lower socket numbers than the applications had been allocated, this does not cause the applications to access data intended for the module-claimed sockets. The possibility should not, however, be ignored.

Module stacks

Complex stacks of components, such as the network stack, may have many dependencies. It is important that, where possible, these dependencies are given due attention to ensure that they are restartable with minimal effort. The Internet module, for example, can be reinitialised and the dependant components will attempt to re-assign a useful system using dynamic allocation of addresses and other methods as configured.