diff -r 43e37759235e -r 51a74ef9ed63 Symbian3/SDK/Source/GUID-301037F1-1983-565A-88F9-633BBF0EBB91.dita --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/SDK/Source/GUID-301037F1-1983-565A-88F9-633BBF0EBB91.dita Wed Mar 31 11:11:55 2010 +0100 @@ -0,0 +1,213 @@ + + + + + +posixsignals: +POSIX Signal Example, Using P.I.P.S.This example demonstrates various signal use cases as supported +in P.I.P.S. +
Purpose

The +example demonstrates the following use cases:

    +
  1. Sending and handling +a signal using the default handler

  2. +
  3. Sending and handling +a signal using a customized signal handler

  4. +
  5. Ignoring an incoming +signal

  6. +
  7. Blocking and releasing +a signal

  8. +
  9. Waiting for a signal

  10. +
  11. Generating and handling +a SIGPIPE signal

  12. +
  13. Using a signal to gracefully +terminate a process

  14. +
  15. Using a signal to handle +an asynchronous event

  16. +

The example delivers 3 sub projects:

    +
  • basicSignals: This +project demonstrates basic signal use cases. It shows the first six use cases +mentioned in the list above. The use cases are demonstrated through basicsignals.exe.

  • +
  • sigtermSignal: This +project demonstrates the graceful termination of a process using the SIGTERM signal. +The use case is demonstrated through sigtermsignal.exe and raisesignal.exe.

  • +
  • asyncSignal: This +project demonstrates asynchronous signal handling using the SIGUSR1 signal +and the SIGUSR2 signal. The use case is demonstrated using sigusr1.exe and sigusr2.exe.

  • +
+
Description

The +use cases demonstrated in this example are described below.

Note: For +clarity in the documentation for this example, signal names have been given +in capitals whilst process names have been given in lower case.

1. +Sending and handling a signal using the default handler

The default +implementation of the signals supported in P.I.P.S. will either terminate +a process or ignore a process. Signals are generated using the Kill() method +and they are handled as per the implementation in the default handler.

To +demonstrate this use case we use SIGCHLD and SIGALRM signals. SIGCHLD by +default gets ignored whenever it is raised, whereas SIGALRM causes +a process termination when raised. As a result the example terminates whenever SIGALRM is +raised, whereas an info message is printed when SIGCHLD is +raised.

2. Sending and handling a signal using a customized signal +handler

To override the default implementation of a signal a +customized handler can be defined. This customized handler can be set either +by using sigaction() or signal(). The sigaction() method +takes struct sigaction as one of its parameters (the sa_handler member +of this structure is filled with the custom handler). Now whenever a signal +is generated the custom handler is executed.

For the demonstration +of this particular use case, SIGCHLD and SIGALRM signals +are used. These signals are assigned custom handler functions. The handlers +for these signals contains a simple user message. Thus, whenever the signals +are raised, the customized signal handlers get invoked instead of the default +handlers.

3. Ignoring an incoming signal

A signal +can be ignored by setting SIG_IGN in the sa_handler member +of struct sigaction. The demonstration of this use case also +uses SIGCHLD and SIGALRM signals, and as +a result of setting SIG_IGN in sa_handler the +signals are ignored when raised.

4. Blocking and releasing a signal

A +signal can be blocked by first adding it to the blocking set (a list of signals +we want to block, when a signal is executing) by using the sigaddset() method +and then calling the sigprocmask() function. Once a signal +is blocked it will always be ignored upon generation. The sigrelse() method +is used to unblock a signal.

Demonstration of this use case involves +the SIGUSR1 and SIGUSR2 signals. Both SIGUSR1 and SIGUSR2 are +user-defined signals. We first block the SIGUSR1 signal by +adding it to the blocking set and making a call to the sigprocmask() function. +Now whenever SIGUSR1 is raised it will get ignored as it +is blocked. SIGUSR1 will keep waiting in the pending queue +until it is released. The release of SIGUSR1 happens in the SIGUSR2 signal +handler. Once SIGUSR1 is released, it is removed from the +pending queue and its handler function is called to handle it.

5. +Waiting for a signal

Before a process can wait on a particular +signal, it has to add the signal to the mask set (which is a list of signals +we want to block) and then call the sigprocmask() method. +The process then sets the timeout value using struct timespec. +Once this is done the process waits on a signal for a specified time period +using thesigtimedwait() method. If the signal is not received +within the specified time period, an error message is generated.

For +the demonstration of this use case we are setting a timeout of 5 seconds. +The SIGALRM signal is raised by a call to alarm() as +and when the timer expires. There are two instances in the example where SIGALRM signal +is raised, one after a duration of 4 seconds and one after 6 seconds. When SIGALRM is +raised after 4 seconds, it is well within the timeout limit (of 5 seconds) +and hence the signal gets received but not handled. But when the alarm is +raised after 6 seconds, timeout happens and an error is generated. Now as +the SIGALRM signal was added to the mask set it never gets +handled even though it is received. To handle the signal we need to move it +from block state to unblock state, which we do using the sigprocmask() method. +Once the signal gets unblocked its custom handler gets called.

6. +Generating and handling a SIGPIPE signal

The + SIGPIPE signal is generated when writing to a broken pipe. +To achieve this broken pipe condition the read end of the pipe (obtained using +the pipe() function call) is closed and then write to the +pipe is done. The associated handler function is executed in response to the +raised SIGPIPE signal .

7. Using a signal to gracefully +terminate a process

Graceful termination of process can be achieved +by using the SIGTERM signal. In the handler function of the +signal all the opened file descriptors need to be closed before exiting.

This +use case is demonstrated using the sigtermSignal project. +The project consists of two processes: the sigtermsignal process +and the raisesignal process.

    +
  • The sigtermsignal process +first defines a custom handler for the SIGTERM signal that +carries out the closing of all the open file descriptors when the signal is +raised. This is done in order to achieve the graceful termination of the process. +The sigtermsignal process then opens a file and obtains +names from user to be written in to it. It then simultaneously spawns a raisesignal process +and starts reading from the file. When the raisesignal process +sends a SIGTERM signal to the sigtermsignal process, +the sigtermsignal process closes all the open file descriptors +and prepares to exit.

  • +
  • The raisesignal process +sends the SIGTERM signal to the sigtermsignal process. +The custom handler of the SIGTERM signal takes care of properly +closing all opened file descriptors and then terminating the process. If the +custom handler is not implemented, the default handler will get called, which +will result in process termination without closing any opened file descriptors.

  • +

8. Using a signal to handle an asynchronous event

The +SIGUSR1 and SIGUSR2 signals are used to demonstrate +the handling of an asynchronous event. These signals are sent from one process +to another. On reception of these signals, respective custom handlers are +called and any necessary action is taken. The action taken is purely implementation +dependent .

This use case demonstration is performed using the asyncSignal project. +The project consists of two processes: the sigusr1 process +and the sigusr2 process, where the sigusr1 process +handles the SIGUSR1 signal and sends the SIGUSR2 signal +to the sigusr2 process. Whereas the sigusr2 process +handles the SIGUSR2 signal and sends the SIGUSR1 signal +to the sigusr1 process.

    +
  • The sigusr1 process +assigns a custom handler for the SIGUSR1 signal. It then +opens a file in read and write mode and write some content into the open file. +Once write operation is done the sigusr1 process spawns sigusr2 process +and waits for SIGUSR1 signal from sigusr2 process. +On receiving SIGUSR1 signal sigusr1 process +starts reading from the file. Once reading from the file is done and its contents +are displayed on the console, sigusr1 process sends SIGUSR2 signal +to sigusr2 process. It then closes all its open file +descriptor and prepares to exit.

  • +
  • The sigusr2 process +is spawned from sigusr1 process and it assigns a custom +handler for SIGUSR2 signal. It sends SIGUSR1 signal +to sigusr1 process in order to start file read and then +waits for SIGUSR2 signal from sigusr1 process. +When sigusr2 process receives SIGUSR2 signal +it prepares to exit.

  • +

Hence, the communication between the two processes happens through +the SIGUSR1 and SIGUSR2 signals and asynchronous +signal handling happens.

+
Download

Click +on the following link to download the example: BasicSignals.zip

Click on the following link +to download the example: SigtermSignal.zip

Click on the following link +to download the example: AsyncSignal.zip

To view the BasicSignal +example source click: browseBasicSignals

To view the SigtermSignal example +source click: browseSigtermSignal

To view the AsyncSignal example +source click: browseAsyncSignal

+
Building and +configuring

You can build the example from your IDE or the command +line:

    +
  • If you use an +IDE, import the bld.inf file of the example into your +IDE, and use the build command of the IDE.

  • +
  • If you use the command line, open a command prompt, and set the current +directory to the source code directory of the example. You can then build +the example with the SBSv1 build tools using the following commands:

      +
    • bldmake bldfiles

    • +
    • abld build

    • +

    How to use +bldmake and How +to use abld describe how to use the SBSv1 build tools.

  • +

The example builds the following executables :

    +
  • basicsignals.exe : for basic signal use cases +demonstration.

  • +
  • sigtermsignal.exe : for demonstrating graceful +termination of process .

  • +
  • raisesignal.exe : for sending SIGTERM signal.

  • +
  • sigusr1.exe : for demonstrating asynchronous event +handling , sending SIGUSR2 signal and receiving SIGUSR1 signal.

  • +
  • sigusr2.exe : for sending SIGUSR1 signal +and receiving SIGUSR2 signal.

  • +

in the epoc32\release\winscw\<udeb or urel>\ folder.

+
Running the +example

NOTE :

basicsignals.exe should +be executed first for running the first six uses cases mentioned above.

sigtermsignal.exe should +be executed for running the seventh use case.

sigusr1.exe should +be executed for running the last use case.

The sigtermsignal process +internally spawns the raisesignal process for taking +an input from the user and sending the SIGTERM signal. You +should not run the raisesignal process explicitly. You +should only run sigtermsignal.exe as the sigtermsignal process +takes proper care of launching the raisesignal process.

The sigusr1 process +also internally spawns the sigusr2 process.

The sigusr1 process +sends the SIGUSR2 signal to the sigusr2 process +and receives the SIGUSR1 signal from it.

The sigusr2 process +sends the SIGUSR1 signal to the sigusr1 process +and receives the SIGUSR2 signal from it.

As the sigusr1 process +spawns the sigusr2 process, hence you should run sigusr1.exe only.

In +order to toggle between the processes use Alt+ctrl+shift+T and +observe the behavior.

+
\ No newline at end of file