summaryrefslogtreecommitdiff
path: root/TAO/orbsvcs/orbsvcs/Event/EC_Thread_Flags.cpp
blob: 98a8e5f7ae54f1f0c9341457cb6dbf5265ccd632 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// $Id$

#include "orbsvcs/Event/EC_Thread_Flags.h"

#include "ace/OS_NS_Thread.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_strings.h"
#include "ace/Log_Msg.h"
#include "ace/Sched_Params.h"

ACE_RCSID(Event, EC_Thread_Flags , "$Id$")

#define TETFSF(flag)  { #flag, flag }
TAO_EC_Thread_Flags::Supported_Flag TAO_EC_Thread_Flags::supported_flags_[] = {
#if defined (ACE_HAS_THREADS)
    TETFSF(THR_CANCEL_DISABLE),
    TETFSF(THR_CANCEL_ENABLE),
    TETFSF(THR_CANCEL_DEFERRED),
    TETFSF(THR_CANCEL_ASYNCHRONOUS),
    TETFSF(THR_BOUND),
    TETFSF(THR_NEW_LWP),
    TETFSF(THR_DETACHED),
    TETFSF(THR_SUSPENDED),
    TETFSF(THR_DAEMON),
    TETFSF(THR_JOINABLE),
    TETFSF(THR_SCHED_FIFO),
    TETFSF(THR_SCHED_RR),
    TETFSF(THR_SCHED_DEFAULT),
    TETFSF(THR_EXPLICIT_SCHED),
    TETFSF(THR_SCOPE_SYSTEM),
    TETFSF(THR_SCOPE_PROCESS)
#endif /* ACE_HAS_THREADS */
  };
#undef TETFSF

TAO_BEGIN_VERSIONED_NAMESPACE_DECL

TAO_EC_Thread_Flags::~TAO_EC_Thread_Flags ()
{
}

void
TAO_EC_Thread_Flags::parse_symbols (const char* syms)
{
  // PRE: we assume nothing other than that syms is valid
  // POST:
  // 1. flags_ is bitwise-OR of all flags
  // 2. sched_ is THR_SCHED_*, or THR_SCHED_DEFAULT if not specified
  // 3. scope_ is THR_SCOPE_*, or THR_SCOPE_PROCESS if not specified

  // NOTE: I'm not sure if #2 and #3 are consistent with what happens
  // in ACE_Task::activate.  I really need to double-check that, and
  // make sure that they are consistent.

  flags_ = scope_ = sched_ = 0; // zero out everything

  // short-circuit on the trivial case
  if (syms == 0 || *syms == '\0')
    return;

  static size_t num_flags = sizeof(supported_flags_)/sizeof(Supported_Flag);
  char* s = ACE_OS_String::strdup (syms); // need a mutable string
  if (s == 0)
    return;

  const char* SEPARATORS = " |"; // this should probably be at class level
  char* ptr = 0;
  char* tok = ACE_OS_String::strtok_r (s, SEPARATORS, &ptr);
  while (tok != 0)
    {
      // This would allow for easy accomodation of flags that
      // aren't currently supported, but is it a good idea?

      if (tok[0] >= '0' && tok[0] <= '9') // Numeric, so just accept it!
        {
          // parse it as a long straight to the flags
 
          // If somebody specifies the scheduler this way, then they
          // lose range checking on the priority.  Bummer, but those
          // are the breaks.
          this->flags_ |= ACE_OS_String::strtol (tok, 0, 0);
        }
      else
        {
          int found = 0;
          for (size_t i = 0; !found && i < num_flags; ++i)
            {
              if (ACE_OS_String::strcasecmp (tok, supported_flags_[i].n) == 0)
                {
                  this->flags_ |= supported_flags_[i].v;

                  // Can't use a switch for this b/c for some
                  // platforms the THR_* constants end up with
                  // the same values, and compiles get upset.
                  long &sf = supported_flags_[i].v;
                  if (sf == THR_SCHED_FIFO ||
                      sf == THR_SCHED_RR ||
                      sf == THR_SCHED_DEFAULT)
                    {
                      this->sched_ = supported_flags_[i].v;
                    }
                  else if (sf == THR_SCOPE_SYSTEM ||
                           sf == THR_SCOPE_PROCESS)
                    {
                      this->scope_ = supported_flags_[i].v;
                    }
                  found = 1;
                }
            }
          if (!found)
            {
              // Ideally this would call some sort of on-error function...
              // but, it doesn't.
              ACE_ERROR ((LM_ERROR,
                          "RTEC (%P|%t) unable to parse %s as a thread flag - skipping\n",
                          tok));
            }
        }
      tok = ACE_OS_String::strtok_r (0, SEPARATORS, &ptr);
    }

  ACE_OS::free (s); // clean up after ourselves
}

long
TAO_EC_Thread_Flags::default_priority () const
{
  long priority = ACE_DEFAULT_THREAD_PRIORITY;

  // use the implementation
  if (this->sched() == 0)
    return priority;

  priority =
    ACE_Sched_Params::priority_min (this->sched()) +
    ACE_Sched_Params::priority_max (this->sched()) / 2;
  priority = ACE_Sched_Params::next_priority (this->sched(), priority);

  return priority;
}

TAO_END_VERSIONED_NAMESPACE_DECL