Single and Multiple Threads

This section describes the threads used in C programs.

Threads

The POSIX interface is designed for a single thread of execution within a process. Many aspects of this interface do not apply to a typical Symbian program in which multiple threads of execution share the same address space. For information about threads and processes, see Threads and processes .

STDLIB allows for multiple threads, but each thread owns its own instance of the _reent structure which contains private data such as the thread's errno variable. Each thread's STDIO FILE structures are completely separate from other threads', even if those structures eventually share the same underlying file descriptor. A consequence of this is that different threads will buffer their output to stdout separately, even though the eventual output will be combined together when the STDIO layer flushes the buffers out to the corresponding file descriptor.

It is unclear how some POSIX functions should be used in a multiple thread environment. An example is the exit() function. Although each thread should have separate atexit() processing, which should include closing all open STDIO files, it is unclear whether closing the STDIO file should also close the underlying descriptor. STDLIB's current implementation is to close the files, as would be expected to happen in a normal POSIX process. However, this implementation may be changed. Note that exit() does not attempt to free memory which was obtained by malloc() .

The user of STDLIB can take control over thread termination by implementing exit() , _exit() , abort() and _assert() in their own program, so that all of the user's own code which calls these functions will invoke the user's routines instead of the STDLIB versions. A helper function, _atexit_processing_r() , can be called from the user's version of exit() to do the normal atexit processing, if desired. See stdlib_r.h for details.

Single-threaded programs

Simple C programs may not need to support file descriptors shared between threads, or the execution of sub-processes. Such programs may use the default implementation of STDLIB, in which the library code opens files, sockets etc. in the context of the calling thread, and provides a per-thread table of open file descriptors.

Multiple threads may still be used, but each thread's resources are private and cannot be shared with other threads. For example, a setenv() call in one thread will not be seen by a getenv() call in another and each thread will have a separate console window (created on demand when the console is first read from or written to).

Multi-threaded programs; the CPosixServer

More complex programs may need to use process-wide resources. This is often true of programs which assume the existence of support for multiple threads within a POSIX process. To meet this requirement, STDLIB can operate in a mode in which all shareable resources are owned by a single CPosixServer thread. In this mode, library routines such as open() , read() and write() operate by passing an appropriate request to the CPosixServer .

The program's mode of operation is determined when it first tries to use STDLIB's services. If a CPosixServer is running for the Symbian platform process, the thread will use it; otherwise the program will operate in the single-threaded mode.

The CPosixServer is a Symbian platform active object, and can be started either in the context of an existing active scheduler, or by spawning a separate thread to run an active scheduler. The functions for doing this have a C++ interface, defined in estlib.h . For more information on active objects, see active objects .

Communication between CPosixServer s is used to establish the POSIX process hierarchy and to communicate resources from parent to child. Programs which require multiple processes must use the multi-threaded mode of operation.