source: rtems/cpukit/rtems/src/eventtimeout.c @ 62da44e

4.115
Last change on this file since 62da44e was 62da44e, checked in by Sebastian Huber <sebastian.huber@…>, on 06/05/13 at 12:09:38

rtems: Move unnest dispatch after ISR enable

This prevents a lock order reversal.

  • Property mode set to 100644
File size: 2.3 KB
Line 
1/**
2 *  @file
3 *
4 *  @brief Timeout Event
5 *  @ingroup ClassicEvent
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2008.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18  #include "config.h"
19#endif
20
21#include <rtems/rtems/event.h>
22
23void _Event_Timeout(
24  Objects_Id  id,
25  void       *arg
26)
27{
28  Thread_Control                   *the_thread;
29  Objects_Locations                 location;
30  ISR_Level                         level;
31  Thread_blocking_operation_States *sync_state;
32
33  sync_state = arg;
34
35  the_thread = _Thread_Get( id, &location );
36  switch ( location ) {
37
38    case OBJECTS_LOCAL:
39
40      /*
41       *  If the event manager is not synchronized, then it is either
42       *  "nothing happened", "timeout", or "satisfied".   If the_thread
43       *  is the executing thread, then it is in the process of blocking
44       *  and it is the thread which is responsible for the synchronization
45       *  process.
46       *
47       *  If it is not satisfied, then it is "nothing happened" and
48       *  this is the "timeout" transition.  After a request is satisfied,
49       *  a timeout is not allowed to occur.
50       */
51      _ISR_Disable( level );
52        /*
53         * Verify that the thread is still waiting for the event condition.
54         * This test is necessary to avoid state corruption if the timeout
55         * happens after the event condition is satisfied in
56         * _Event_Surrender().  A satisfied event condition is indicated with
57         * count set to zero.
58         */
59        if ( !the_thread->Wait.count ) {
60          _ISR_Enable( level );
61          _Thread_Unnest_dispatch();
62          return;
63        }
64
65        the_thread->Wait.count = 0;
66        if ( _Thread_Is_executing( the_thread ) ) {
67          if ( *sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED )
68            *sync_state = THREAD_BLOCKING_OPERATION_TIMEOUT;
69        }
70
71        the_thread->Wait.return_code = RTEMS_TIMEOUT;
72      _ISR_Enable( level );
73      _Thread_Unblock( the_thread );
74      _Thread_Unnest_dispatch();
75      break;
76
77#if defined(RTEMS_MULTIPROCESSING)
78    case OBJECTS_REMOTE:  /* impossible */
79#endif
80    case OBJECTS_ERROR:
81      break;
82  }
83}
Note: See TracBrowser for help on using the repository browser.