/usr/include/omniORB4/omniAsyncInvoker.h is in libomniorb4-dev 4.2.2-0.8.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | // -*- Mode: C++; -*-
// Package : omniORB
// omniAsyncInvoker.h Created on: 20 Dec 2000
// Authors : Duncan Grisby
// Sai Lai Lo
//
// Copyright (C) 2006-2013 Apasphere Ltd
// Copyright (C) 2000 AT&T Laboratories Cambridge
//
// This file is part of the omniORB library
//
// The omniORB library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library. If not, see http://www.gnu.org/licenses/
//
// Description:
// *** PROPRIETARY INTERFACE ***
//
#ifndef __OMNIASYNCINVOKER_H__
#define __OMNIASYNCINVOKER_H__
// Usage:
//
// An omniAsyncInvoker, or an invoker in short, is an object that
// executes commands asynchronously using a pool of threads it manages
// internally.
//
// The command to be executed is an omniTask instance. The omniTask
// class is based on the Command Pattern (Design Patterns, chapter 5).
//
// The client creates an instance of the omniTask and registers it with
// the omniAsyncInvoker using the insert() method. The invoker will
// dispatch a thread to call the execute() method in the omniTask object.
// Notice that the call to the execute() method is always done by
// another thread, hence giving the invoker its asynchronous nature.
//
// Depending on the category of an omniTask, the invoker will
// choose a thread to execute the task in one of the following
// ways:
//
// AnyTime: the task will be executed by one of the threads in the
// pool. If no thread is available, the task may be queued
// indefinitely until a thread is available
//
// DedicatedThread: the task is executed by a particular thread. This
// is particularly useful if the task involves calling
// into a non-thread safe library and it is desirable
// to always use the same thread to do so.
//
// The thread that will execute the command is always
// the thread that calls the invoker's perform()
// method.
//
// Notice that the task may never be dispatched if
// no external thread calls perform().
//
// ImmediateDispatch: A thread will be dispatched to execute the task
// immediately.
//
// To do so the invoker may have to spawn a new
// thread to do the work. If the invoker fails to
// spawn a thread for various reasons, the insert()
// call fails.
//
// Once the execute() method is called on a task, the invoker will forget
// about it. If the task object is heap allocated, it has to be garbage
// collected by some external means. The simplist approach is to delete
// the task object before the execute() method returns.
class omniAsyncPool;
class omniAsyncDedicated;
class omniAsyncWorker;
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
class omniTaskLink {
public:
omniTaskLink* next;
omniTaskLink* prev;
inline omniTaskLink()
{
next = prev = this;
}
inline void enq(omniTaskLink& head)
{
next = head.prev->next;
head.prev->next = this;
prev = head.prev;
head.prev = this;
}
inline void deq()
{
prev->next = next;
next->prev = prev;
}
static inline unsigned int is_empty(omniTaskLink& head)
{
return (head.next == &head);
}
private:
omniTaskLink(const omniTaskLink&);
omniTaskLink& operator=(const omniTaskLink&);
};
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
class omniTask : public omniTaskLink {
public:
// What sort of task dispatch?
enum Category { AnyTime, // Run whenever a thread is free
ImmediateDispatch, // Run immediately
DedicatedThread // Use the dedicated thread
};
// What is this task doing?
enum Purpose { General, // General task
ServerUpcall, // Server-side upcall into application code
ClientInvocation // Client-side operation invocation
};
virtual void execute() = 0;
inline omniTask(Category cat = AnyTime, Purpose pur = General)
: pd_category(cat), pd_purpose(pur), pd_self(0) {}
virtual ~omniTask() {}
inline Category category() { return pd_category; }
inline void category(Category c) { pd_category = c; }
inline Purpose purpose() { return pd_purpose; }
inline void purpose(Purpose p) { pd_purpose = p; }
inline omni_thread* selfThread() { return pd_self; }
// The worker thread assigned to handle the task. Set by the worker.
private:
Category pd_category;
Purpose pd_purpose;
omni_thread* pd_self;
omniTask(const omniTask&);
omniTask& operator=(const omniTask&);
friend class omniAsyncWorker;
};
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////
class omniAsyncInvoker {
public:
omniAsyncInvoker();
// Constructor.
virtual ~omniAsyncInvoker();
// Returns only when all the threads doing Anytime tasks have exited.
// Notice that any tasks still sitting on the pending queues will be
// discarded quietly.
CORBA::Boolean insert(omniTask*);
// insert the task into the correct pending queue. The task will be
// dispatched according to its category.
//
// returns 1 if the task has been inserted successfully.
// returns 0 if the task cannot be inserted.
CORBA::Boolean work_pending();
// Return 1 if there are DedicatedThread tasks pending, 0 if none.
void perform(unsigned long secs = 0, unsigned long nanosecs = 0);
// Loop performing dedicated thread tasks. If a timeout is
// specified, returns when the absolute time passes; otherwise,
// blocks until shut down.
void shutdown();
// Release threads blocked in perform.
static _core_attr unsigned int idle_timeout;
// No. of seconds an idle thread waits before it exits. default is
// 10 seconds.
private:
omniAsyncWorker* getWorker(omniAsyncPool* pool);
inline unsigned int workerStart()
{
omni_tracedmutex_lock l(pd_lock);
return ++pd_total_threads;
}
inline unsigned int workerStartLocked()
{
ASSERT_OMNI_TRACEDMUTEX_HELD(pd_lock, 1);
return ++pd_total_threads;
}
inline unsigned int workerStop()
{
omni_tracedmutex_lock l(pd_lock);
if (--pd_total_threads == 0)
pd_idle_cond.broadcast();
return pd_total_threads;
}
omni_tracedmutex pd_lock;
omni_tracedcondition pd_idle_cond;
unsigned int pd_total_threads; // Total number of threads.
omniAsyncWorker* pd_idle_threads;
omniAsyncPool* pd_general; // General threads/tasks
omniAsyncPool* pd_server; // Server threads/tasks
omniAsyncPool* pd_client; // Client threads/tasks
omniAsyncDedicated* pd_dedicated; // Dedicated tasks
CORBA::Boolean pd_keep_working;
friend class omniAsyncWorker;
friend class omniAsyncPool;
friend class omniAsyncDedicated;
};
#endif // __OMNIASYNCINVOKER_H__
|