Skip to content

Using the API with threads

cantora edited this page Aug 21, 2013 · 3 revisions

General Expectations

  • A plugin must not make any API calls from within a callback, as this will result in thread lock because aug locks various resources when making callbacks as well as when performing API tasks. The only exceptions are given in the section below.
  • A plugin must not make any API calls in between calls to lock_screen and unlock_screen. Most API calls will lock the screen when invoked, thus deadlock will result if the screen (i.e. ncurses API) is already locked. The exceptions to this rule are given in the section below.

API calls which can be invoked from within a callback or after lock_screen

  • screen_doupdate
  • screen_panel_update
  • primary_term_damage
  • log
  • conf_val
  • terminal_pid
  • terminal_terminated

Caveats

A warning: simply following the above rules does not guarantee a plugin will avoid deadlock. Below is an example of a circular dependency which can cause a deadlock despite the fact that it breaks none of the rules given above.

Do not wait on any locks which another thread may have locked when that other thread may be making API calls; this will cause a circular dependency and most likely the threads will become deadlocked. For example:

 *    __________________________________________________
 *   | aug thread             |   plugin thread1        |
 *   |------------------------|-------------------------|
 *   |                        |   *locks mtx1*          |
 *   |  *locks api*           |                         |
 *   |  invokes api callback  |                         |
 *   |(now in plugin callback)|                         |
 *   |*locks mtx1* (blocked)  |                         | <- (1)
 *   |                        | makes api call (blocked)| <- (2)
 *   |------------------------|-------------------------|
 *   |                    DEADLOCKED                    |
 *
 *   (1) the aug thread cant unlock the api until the callback completes
 *   (2) the callback will never complete until thread1 does its business
 *       and unlocks mtx1, but thread1 is blocked on the api call because
 *       the api is locked.
 */