lh | 9ed821d | 2023-04-07 01:36:19 -0700 | [diff] [blame^] | 1 | @node Non-Local Exits, Signal Handling, Resource Usage And Limitation, Top |
| 2 | @c %MENU% Jumping out of nested function calls |
| 3 | @chapter Non-Local Exits |
| 4 | @cindex non-local exits |
| 5 | @cindex long jumps |
| 6 | |
| 7 | Sometimes when your program detects an unusual situation inside a deeply |
| 8 | nested set of function calls, you would like to be able to immediately |
| 9 | return to an outer level of control. This section describes how you can |
| 10 | do such @dfn{non-local exits} using the @code{setjmp} and @code{longjmp} |
| 11 | functions. |
| 12 | |
| 13 | @menu |
| 14 | * Intro: Non-Local Intro. When and how to use these facilities. |
| 15 | * Details: Non-Local Details. Functions for non-local exits. |
| 16 | * Non-Local Exits and Signals:: Portability issues. |
| 17 | * System V contexts:: Complete context control a la System V. |
| 18 | @end menu |
| 19 | |
| 20 | @node Non-Local Intro, Non-Local Details, , Non-Local Exits |
| 21 | @section Introduction to Non-Local Exits |
| 22 | |
| 23 | As an example of a situation where a non-local exit can be useful, |
| 24 | suppose you have an interactive program that has a ``main loop'' that |
| 25 | prompts for and executes commands. Suppose the ``read'' command reads |
| 26 | input from a file, doing some lexical analysis and parsing of the input |
| 27 | while processing it. If a low-level input error is detected, it would |
| 28 | be useful to be able to return immediately to the ``main loop'' instead |
| 29 | of having to make each of the lexical analysis, parsing, and processing |
| 30 | phases all have to explicitly deal with error situations initially |
| 31 | detected by nested calls. |
| 32 | |
| 33 | (On the other hand, if each of these phases has to do a substantial |
| 34 | amount of cleanup when it exits---such as closing files, deallocating |
| 35 | buffers or other data structures, and the like---then it can be more |
| 36 | appropriate to do a normal return and have each phase do its own |
| 37 | cleanup, because a non-local exit would bypass the intervening phases and |
| 38 | their associated cleanup code entirely. Alternatively, you could use a |
| 39 | non-local exit but do the cleanup explicitly either before or after |
| 40 | returning to the ``main loop''.) |
| 41 | |
| 42 | In some ways, a non-local exit is similar to using the @samp{return} |
| 43 | statement to return from a function. But while @samp{return} abandons |
| 44 | only a single function call, transferring control back to the point at |
| 45 | which it was called, a non-local exit can potentially abandon many |
| 46 | levels of nested function calls. |
| 47 | |
| 48 | You identify return points for non-local exits by calling the function |
| 49 | @code{setjmp}. This function saves information about the execution |
| 50 | environment in which the call to @code{setjmp} appears in an object of |
| 51 | type @code{jmp_buf}. Execution of the program continues normally after |
| 52 | the call to @code{setjmp}, but if an exit is later made to this return |
| 53 | point by calling @code{longjmp} with the corresponding @w{@code{jmp_buf}} |
| 54 | object, control is transferred back to the point where @code{setjmp} was |
| 55 | called. The return value from @code{setjmp} is used to distinguish |
| 56 | between an ordinary return and a return made by a call to |
| 57 | @code{longjmp}, so calls to @code{setjmp} usually appear in an @samp{if} |
| 58 | statement. |
| 59 | |
| 60 | Here is how the example program described above might be set up: |
| 61 | |
| 62 | @smallexample |
| 63 | @include setjmp.c.texi |
| 64 | @end smallexample |
| 65 | |
| 66 | The function @code{abort_to_main_loop} causes an immediate transfer of |
| 67 | control back to the main loop of the program, no matter where it is |
| 68 | called from. |
| 69 | |
| 70 | The flow of control inside the @code{main} function may appear a little |
| 71 | mysterious at first, but it is actually a common idiom with |
| 72 | @code{setjmp}. A normal call to @code{setjmp} returns zero, so the |
| 73 | ``else'' clause of the conditional is executed. If |
| 74 | @code{abort_to_main_loop} is called somewhere within the execution of |
| 75 | @code{do_command}, then it actually appears as if the @emph{same} call |
| 76 | to @code{setjmp} in @code{main} were returning a second time with a value |
| 77 | of @code{-1}. |
| 78 | |
| 79 | @need 250 |
| 80 | So, the general pattern for using @code{setjmp} looks something like: |
| 81 | |
| 82 | @smallexample |
| 83 | if (setjmp (@var{buffer})) |
| 84 | /* @r{Code to clean up after premature return.} */ |
| 85 | @dots{} |
| 86 | else |
| 87 | /* @r{Code to be executed normally after setting up the return point.} */ |
| 88 | @dots{} |
| 89 | @end smallexample |
| 90 | |
| 91 | @node Non-Local Details, Non-Local Exits and Signals, Non-Local Intro, Non-Local Exits |
| 92 | @section Details of Non-Local Exits |
| 93 | |
| 94 | Here are the details on the functions and data structures used for |
| 95 | performing non-local exits. These facilities are declared in |
| 96 | @file{setjmp.h}. |
| 97 | @pindex setjmp.h |
| 98 | |
| 99 | @comment setjmp.h |
| 100 | @comment ISO |
| 101 | @deftp {Data Type} jmp_buf |
| 102 | Objects of type @code{jmp_buf} hold the state information to |
| 103 | be restored by a non-local exit. The contents of a @code{jmp_buf} |
| 104 | identify a specific place to return to. |
| 105 | @end deftp |
| 106 | |
| 107 | @comment setjmp.h |
| 108 | @comment ISO |
| 109 | @deftypefn Macro int setjmp (jmp_buf @var{state}) |
| 110 | @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} |
| 111 | @c _setjmp ok |
| 112 | @c __sigsetjmp(!savemask) ok |
| 113 | @c __sigjmp_save(!savemask) ok, does not call sigprocmask |
| 114 | When called normally, @code{setjmp} stores information about the |
| 115 | execution state of the program in @var{state} and returns zero. If |
| 116 | @code{longjmp} is later used to perform a non-local exit to this |
| 117 | @var{state}, @code{setjmp} returns a nonzero value. |
| 118 | @end deftypefn |
| 119 | |
| 120 | @comment setjmp.h |
| 121 | @comment ISO |
| 122 | @deftypefun void longjmp (jmp_buf @var{state}, int @var{value}) |
| 123 | @safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}} |
| 124 | @c __libc_siglongjmp @ascuplugin @asucorrupt @asulock/hurd @acucorrupt @aculock/hurd |
| 125 | @c _longjmp_unwind @ascuplugin @asucorrupt @acucorrupt |
| 126 | @c __pthread_cleanup_upto @ascuplugin @asucorrupt @acucorrupt |
| 127 | @c plugins may be unsafe themselves, but even if they weren't, this |
| 128 | @c function isn't robust WRT async signals and cancellation: |
| 129 | @c cleanups aren't taken off the stack right away, only after all |
| 130 | @c cleanups have been run. This means that async-cancelling |
| 131 | @c longjmp, or interrupting longjmp with an async signal handler |
| 132 | @c that calls longjmp may run the same cleanups multiple times. |
| 133 | @c _JMPBUF_UNWINDS_ADJ ok |
| 134 | @c *cleanup_buf->__routine @ascuplugin |
| 135 | @c sigprocmask(SIG_SETMASK) dup @asulock/hurd @aculock/hurd |
| 136 | @c __longjmp ok |
| 137 | This function restores current execution to the state saved in |
| 138 | @var{state}, and continues execution from the call to @code{setjmp} that |
| 139 | established that return point. Returning from @code{setjmp} by means of |
| 140 | @code{longjmp} returns the @var{value} argument that was passed to |
| 141 | @code{longjmp}, rather than @code{0}. (But if @var{value} is given as |
| 142 | @code{0}, @code{setjmp} returns @code{1}).@refill |
| 143 | @end deftypefun |
| 144 | |
| 145 | There are a lot of obscure but important restrictions on the use of |
| 146 | @code{setjmp} and @code{longjmp}. Most of these restrictions are |
| 147 | present because non-local exits require a fair amount of magic on the |
| 148 | part of the C compiler and can interact with other parts of the language |
| 149 | in strange ways. |
| 150 | |
| 151 | The @code{setjmp} function is actually a macro without an actual |
| 152 | function definition, so you shouldn't try to @samp{#undef} it or take |
| 153 | its address. In addition, calls to @code{setjmp} are safe in only the |
| 154 | following contexts: |
| 155 | |
| 156 | @itemize @bullet |
| 157 | @item |
| 158 | As the test expression of a selection or iteration |
| 159 | statement (such as @samp{if}, @samp{switch}, or @samp{while}). |
| 160 | |
| 161 | @item |
| 162 | As one operand of an equality or comparison operator that appears as the |
| 163 | test expression of a selection or iteration statement. The other |
| 164 | operand must be an integer constant expression. |
| 165 | |
| 166 | @item |
| 167 | As the operand of a unary @samp{!} operator, that appears as the |
| 168 | test expression of a selection or iteration statement. |
| 169 | |
| 170 | @item |
| 171 | By itself as an expression statement. |
| 172 | @end itemize |
| 173 | |
| 174 | Return points are valid only during the dynamic extent of the function |
| 175 | that called @code{setjmp} to establish them. If you @code{longjmp} to |
| 176 | a return point that was established in a function that has already |
| 177 | returned, unpredictable and disastrous things are likely to happen. |
| 178 | |
| 179 | You should use a nonzero @var{value} argument to @code{longjmp}. While |
| 180 | @code{longjmp} refuses to pass back a zero argument as the return value |
| 181 | from @code{setjmp}, this is intended as a safety net against accidental |
| 182 | misuse and is not really good programming style. |
| 183 | |
| 184 | When you perform a non-local exit, accessible objects generally retain |
| 185 | whatever values they had at the time @code{longjmp} was called. The |
| 186 | exception is that the values of automatic variables local to the |
| 187 | function containing the @code{setjmp} call that have been changed since |
| 188 | the call to @code{setjmp} are indeterminate, unless you have declared |
| 189 | them @code{volatile}. |
| 190 | |
| 191 | @node Non-Local Exits and Signals, System V contexts, Non-Local Details, Non-Local Exits |
| 192 | @section Non-Local Exits and Signals |
| 193 | |
| 194 | In BSD Unix systems, @code{setjmp} and @code{longjmp} also save and |
| 195 | restore the set of blocked signals; see @ref{Blocking Signals}. However, |
| 196 | the POSIX.1 standard requires @code{setjmp} and @code{longjmp} not to |
| 197 | change the set of blocked signals, and provides an additional pair of |
| 198 | functions (@code{sigsetjmp} and @code{siglongjmp}) to get the BSD |
| 199 | behavior. |
| 200 | |
| 201 | The behavior of @code{setjmp} and @code{longjmp} in @theglibc{} is |
| 202 | controlled by feature test macros; see @ref{Feature Test Macros}. The |
| 203 | default in @theglibc{} is the POSIX.1 behavior rather than the BSD |
| 204 | behavior. |
| 205 | |
| 206 | The facilities in this section are declared in the header file |
| 207 | @file{setjmp.h}. |
| 208 | @pindex setjmp.h |
| 209 | |
| 210 | @comment setjmp.h |
| 211 | @comment POSIX.1 |
| 212 | @deftp {Data Type} sigjmp_buf |
| 213 | This is similar to @code{jmp_buf}, except that it can also store state |
| 214 | information about the set of blocked signals. |
| 215 | @end deftp |
| 216 | |
| 217 | @comment setjmp.h |
| 218 | @comment POSIX.1 |
| 219 | @deftypefun int sigsetjmp (sigjmp_buf @var{state}, int @var{savesigs}) |
| 220 | @safety{@prelim{}@mtsafe{}@asunsafe{@asulock{/hurd}}@acunsafe{@aculock{/hurd}}} |
| 221 | @c sigsetjmp @asulock/hurd @aculock/hurd |
| 222 | @c __sigsetjmp(savemask) @asulock/hurd @aculock/hurd |
| 223 | @c __sigjmp_save(savemask) @asulock/hurd @aculock/hurd |
| 224 | @c sigprocmask(SIG_BLOCK probe) dup @asulock/hurd @aculock/hurd |
| 225 | This is similar to @code{setjmp}. If @var{savesigs} is nonzero, the set |
| 226 | of blocked signals is saved in @var{state} and will be restored if a |
| 227 | @code{siglongjmp} is later performed with this @var{state}. |
| 228 | @end deftypefun |
| 229 | |
| 230 | @comment setjmp.h |
| 231 | @comment POSIX.1 |
| 232 | @deftypefun void siglongjmp (sigjmp_buf @var{state}, int @var{value}) |
| 233 | @safety{@prelim{}@mtsafe{}@asunsafe{@ascuplugin{} @asucorrupt{} @asulock{/hurd}}@acunsafe{@acucorrupt{} @aculock{/hurd}}} |
| 234 | @c Alias to longjmp. |
| 235 | This is similar to @code{longjmp} except for the type of its @var{state} |
| 236 | argument. If the @code{sigsetjmp} call that set this @var{state} used a |
| 237 | nonzero @var{savesigs} flag, @code{siglongjmp} also restores the set of |
| 238 | blocked signals. |
| 239 | @end deftypefun |
| 240 | |
| 241 | @node System V contexts,, Non-Local Exits and Signals, Non-Local Exits |
| 242 | @section Complete Context Control |
| 243 | |
| 244 | The Unix standard provides one more set of functions to control the |
| 245 | execution path and these functions are more powerful than those |
| 246 | discussed in this chapter so far. These function were part of the |
| 247 | original @w{System V} API and by this route were added to the Unix |
| 248 | API. Beside on branded Unix implementations these interfaces are not |
| 249 | widely available. Not all platforms and/or architectures @theglibc{} |
| 250 | is available on provide this interface. Use @file{configure} to |
| 251 | detect the availability. |
| 252 | |
| 253 | Similar to the @code{jmp_buf} and @code{sigjmp_buf} types used for the |
| 254 | variables to contain the state of the @code{longjmp} functions the |
| 255 | interfaces of interest here have an appropriate type as well. Objects |
| 256 | of this type are normally much larger since more information is |
| 257 | contained. The type is also used in a few more places as we will see. |
| 258 | The types and functions described in this section are all defined and |
| 259 | declared respectively in the @file{ucontext.h} header file. |
| 260 | |
| 261 | @comment ucontext.h |
| 262 | @comment SVID |
| 263 | @deftp {Data Type} ucontext_t |
| 264 | |
| 265 | The @code{ucontext_t} type is defined as a structure with at least the |
| 266 | following elements: |
| 267 | |
| 268 | @table @code |
| 269 | @item ucontext_t *uc_link |
| 270 | This is a pointer to the next context structure which is used if the |
| 271 | context described in the current structure returns. |
| 272 | |
| 273 | @item sigset_t uc_sigmask |
| 274 | Set of signals which are blocked when this context is used. |
| 275 | |
| 276 | @item stack_t uc_stack |
| 277 | Stack used for this context. The value need not be (and normally is |
| 278 | not) the stack pointer. @xref{Signal Stack}. |
| 279 | |
| 280 | @item mcontext_t uc_mcontext |
| 281 | This element contains the actual state of the process. The |
| 282 | @code{mcontext_t} type is also defined in this header but the definition |
| 283 | should be treated as opaque. Any use of knowledge of the type makes |
| 284 | applications less portable. |
| 285 | |
| 286 | @end table |
| 287 | @end deftp |
| 288 | |
| 289 | Objects of this type have to be created by the user. The initialization |
| 290 | and modification happens through one of the following functions: |
| 291 | |
| 292 | @comment ucontext.h |
| 293 | @comment SVID |
| 294 | @deftypefun int getcontext (ucontext_t *@var{ucp}) |
| 295 | @safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}} |
| 296 | @c Linux-only implementations in assembly, including sigprocmask |
| 297 | @c syscall. A few cases call the sigprocmask function, but that's safe |
| 298 | @c too. The ppc case is implemented in terms of a swapcontext syscall. |
| 299 | The @code{getcontext} function initializes the variable pointed to by |
| 300 | @var{ucp} with the context of the calling thread. The context contains |
| 301 | the content of the registers, the signal mask, and the current stack. |
| 302 | Executing the contents would start at the point where the |
| 303 | @code{getcontext} call just returned. |
| 304 | |
| 305 | The function returns @code{0} if successful. Otherwise it returns |
| 306 | @code{-1} and sets @var{errno} accordingly. |
| 307 | @end deftypefun |
| 308 | |
| 309 | The @code{getcontext} function is similar to @code{setjmp} but it does |
| 310 | not provide an indication of whether @code{getcontext} is returning for |
| 311 | the first time or whether an initialized context has just been restored. |
| 312 | If this is necessary the user has to determine this herself. This must |
| 313 | be done carefully since the context contains registers which might contain |
| 314 | register variables. This is a good situation to define variables with |
| 315 | @code{volatile}. |
| 316 | |
| 317 | Once the context variable is initialized it can be used as is or it can |
| 318 | be modified using the @code{makecontext} function. The latter is normally |
| 319 | done when implementing co-routines or similar constructs. |
| 320 | |
| 321 | @comment ucontext.h |
| 322 | @comment SVID |
| 323 | @deftypefun void makecontext (ucontext_t *@var{ucp}, void (*@var{func}) (void), int @var{argc}, @dots{}) |
| 324 | @safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@assafe{}@acsafe{}} |
| 325 | @c Linux-only implementations mostly in assembly, nothing unsafe. |
| 326 | |
| 327 | The @var{ucp} parameter passed to @code{makecontext} shall be |
| 328 | initialized by a call to @code{getcontext}. The context will be |
| 329 | modified in a way such that if the context is resumed it will start by |
| 330 | calling the function @code{func} which gets @var{argc} integer arguments |
| 331 | passed. The integer arguments which are to be passed should follow the |
| 332 | @var{argc} parameter in the call to @code{makecontext}. |
| 333 | |
| 334 | Before the call to this function the @code{uc_stack} and @code{uc_link} |
| 335 | element of the @var{ucp} structure should be initialized. The |
| 336 | @code{uc_stack} element describes the stack which is used for this |
| 337 | context. No two contexts which are used at the same time should use the |
| 338 | same memory region for a stack. |
| 339 | |
| 340 | The @code{uc_link} element of the object pointed to by @var{ucp} should |
| 341 | be a pointer to the context to be executed when the function @var{func} |
| 342 | returns or it should be a null pointer. See @code{setcontext} for more |
| 343 | information about the exact use. |
| 344 | @end deftypefun |
| 345 | |
| 346 | While allocating the memory for the stack one has to be careful. Most |
| 347 | modern processors keep track of whether a certain memory region is |
| 348 | allowed to contain code which is executed or not. Data segments and |
| 349 | heap memory are normally not tagged to allow this. The result is that |
| 350 | programs would fail. Examples for such code include the calling |
| 351 | sequences the GNU C compiler generates for calls to nested functions. |
| 352 | Safe ways to allocate stacks correctly include using memory on the |
| 353 | original threads stack or explicitly allocate memory tagged for |
| 354 | execution using (@pxref{Memory-mapped I/O}). |
| 355 | |
| 356 | @strong{Compatibility note}: The current Unix standard is very imprecise |
| 357 | about the way the stack is allocated. All implementations seem to agree |
| 358 | that the @code{uc_stack} element must be used but the values stored in |
| 359 | the elements of the @code{stack_t} value are unclear. @Theglibc{} |
| 360 | and most other Unix implementations require the @code{ss_sp} value of |
| 361 | the @code{uc_stack} element to point to the base of the memory region |
| 362 | allocated for the stack and the size of the memory region is stored in |
| 363 | @code{ss_size}. There are implements out there which require |
| 364 | @code{ss_sp} to be set to the value the stack pointer will have (which |
| 365 | can, depending on the direction the stack grows, be different). This |
| 366 | difference makes the @code{makecontext} function hard to use and it |
| 367 | requires detection of the platform at compile time. |
| 368 | |
| 369 | @comment ucontext.h |
| 370 | @comment SVID |
| 371 | @deftypefun int setcontext (const ucontext_t *@var{ucp}) |
| 372 | @safety{@prelim{}@mtsafe{@mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} |
| 373 | @c Linux-only implementations mostly in assembly. Some ports use |
| 374 | @c sigreturn or swapcontext syscalls; others restore the signal mask |
| 375 | @c first and then proceed restore other registers in userland, which |
| 376 | @c leaves a window for cancellation or async signals with misaligned or |
| 377 | @c otherwise corrupt stack. ??? Switching to a different stack, or even |
| 378 | @c to an earlier state on the same stack, may conflict with pthread |
| 379 | @c cleanups. This is not quite MT-Unsafe, it's a different kind of |
| 380 | @c safety issue. |
| 381 | |
| 382 | The @code{setcontext} function restores the context described by |
| 383 | @var{ucp}. The context is not modified and can be reused as often as |
| 384 | wanted. |
| 385 | |
| 386 | If the context was created by @code{getcontext} execution resumes with |
| 387 | the registers filled with the same values and the same stack as if the |
| 388 | @code{getcontext} call just returned. |
| 389 | |
| 390 | If the context was modified with a call to @code{makecontext} execution |
| 391 | continues with the function passed to @code{makecontext} which gets the |
| 392 | specified parameters passed. If this function returns execution is |
| 393 | resumed in the context which was referenced by the @code{uc_link} |
| 394 | element of the context structure passed to @code{makecontext} at the |
| 395 | time of the call. If @code{uc_link} was a null pointer the application |
| 396 | terminates normally with an exit status value of @code{EXIT_SUCCESS} |
| 397 | (@pxref{Program Termination}). |
| 398 | |
| 399 | If the context was created by a call to a signal handler or from any |
| 400 | other source then the behaviour of @code{setcontext} is unspecified. |
| 401 | |
| 402 | Since the context contains information about the stack no two threads |
| 403 | should use the same context at the same time. The result in most cases |
| 404 | would be disastrous. |
| 405 | |
| 406 | The @code{setcontext} function does not return unless an error occurred |
| 407 | in which case it returns @code{-1}. |
| 408 | @end deftypefun |
| 409 | |
| 410 | The @code{setcontext} function simply replaces the current context with |
| 411 | the one described by the @var{ucp} parameter. This is often useful but |
| 412 | there are situations where the current context has to be preserved. |
| 413 | |
| 414 | @comment ucontext.h |
| 415 | @comment SVID |
| 416 | @deftypefun int swapcontext (ucontext_t *restrict @var{oucp}, const ucontext_t *restrict @var{ucp}) |
| 417 | @safety{@prelim{}@mtsafe{@mtsrace{:oucp} @mtsrace{:ucp}}@asunsafe{@asucorrupt{}}@acunsafe{@acucorrupt{}}} |
| 418 | @c Linux-only implementations mostly in assembly. Some ports call or |
| 419 | @c inline getcontext and/or setcontext, adjusting the saved context in |
| 420 | @c between, so we inherit the potential issues of both. |
| 421 | |
| 422 | The @code{swapcontext} function is similar to @code{setcontext} but |
| 423 | instead of just replacing the current context the latter is first saved |
| 424 | in the object pointed to by @var{oucp} as if this was a call to |
| 425 | @code{getcontext}. The saved context would resume after the call to |
| 426 | @code{swapcontext}. |
| 427 | |
| 428 | Once the current context is saved the context described in @var{ucp} is |
| 429 | installed and execution continues as described in this context. |
| 430 | |
| 431 | If @code{swapcontext} succeeds the function does not return unless the |
| 432 | context @var{oucp} is used without prior modification by |
| 433 | @code{makecontext}. The return value in this case is @code{0}. If the |
| 434 | function fails it returns @code{-1} and sets @var{errno} accordingly. |
| 435 | @end deftypefun |
| 436 | |
| 437 | @heading Example for SVID Context Handling |
| 438 | |
| 439 | The easiest way to use the context handling functions is as a |
| 440 | replacement for @code{setjmp} and @code{longjmp}. The context contains |
| 441 | on most platforms more information which may lead to fewer surprises |
| 442 | but this also means using these functions is more expensive (besides |
| 443 | being less portable). |
| 444 | |
| 445 | @smallexample |
| 446 | int |
| 447 | random_search (int n, int (*fp) (int, ucontext_t *)) |
| 448 | @{ |
| 449 | volatile int cnt = 0; |
| 450 | ucontext_t uc; |
| 451 | |
| 452 | /* @r{Safe current context.} */ |
| 453 | if (getcontext (&uc) < 0) |
| 454 | return -1; |
| 455 | |
| 456 | /* @r{If we have not tried @var{n} times try again.} */ |
| 457 | if (cnt++ < n) |
| 458 | /* @r{Call the function with a new random number} |
| 459 | @r{and the context}. */ |
| 460 | if (fp (rand (), &uc) != 0) |
| 461 | /* @r{We found what we were looking for.} */ |
| 462 | return 1; |
| 463 | |
| 464 | /* @r{Not found.} */ |
| 465 | return 0; |
| 466 | @} |
| 467 | @end smallexample |
| 468 | |
| 469 | Using contexts in such a way enables emulating exception handling. The |
| 470 | search functions passed in the @var{fp} parameter could be very large, |
| 471 | nested, and complex which would make it complicated (or at least would |
| 472 | require a lot of code) to leave the function with an error value which |
| 473 | has to be passed down to the caller. By using the context it is |
| 474 | possible to leave the search function in one step and allow restarting |
| 475 | the search which also has the nice side effect that it can be |
| 476 | significantly faster. |
| 477 | |
| 478 | Something which is harder to implement with @code{setjmp} and |
| 479 | @code{longjmp} is to switch temporarily to a different execution path |
| 480 | and then resume where execution was stopped. |
| 481 | |
| 482 | @smallexample |
| 483 | @include swapcontext.c.texi |
| 484 | @end smallexample |
| 485 | |
| 486 | This an example how the context functions can be used to implement |
| 487 | co-routines or cooperative multi-threading. All that has to be done is |
| 488 | to call every once in a while @code{swapcontext} to continue running a |
| 489 | different context. It is not recommended to do the context switching from |
| 490 | the signal handler directly since leaving the signal handler via |
| 491 | @code{setcontext} if the signal was delivered during code that was not |
| 492 | asynchronous signal safe could lead to problems. Setting a variable in |
| 493 | the signal handler and checking it in the body of the functions which |
| 494 | are executed is a safer approach. Since @code{swapcontext} is saving the |
| 495 | current context it is possible to have multiple different scheduling points |
| 496 | in the code. Execution will always resume where it was left. |