summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbala <balanatarajan@users.noreply.github.com>2004-01-07 19:25:26 +0000
committerbala <balanatarajan@users.noreply.github.com>2004-01-07 19:25:26 +0000
commitac79b51064f2c2d31585008a12ffca823a54212a (patch)
treeafd5752c6d292bd0925b99f3d70a69cdd0a65e91
parent1e3c85e93121b49a5fe2a297a77c0f156a4db86e (diff)
downloadATCD-ac79b51064f2c2d31585008a12ffca823a54212a.tar.gz
ChangeLogTag:
-rw-r--r--ChangeLog22
-rw-r--r--ace/OS_NS_Thread.h10
-rw-r--r--ace/OS_NS_Thread.inl66
3 files changed, 76 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index dc3e69c2c3c..cca2bbcd242 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Wed Jan 7 13:09:27 2004 Balachandran Natarajan <bala@dre.vanderbilt.edu>
+
+ * ace/OS_NS_Thread.inl:
+ * ace/OS_NS_Thread.h:
+
+ The following checkin "Mon Jan 5 11:02:55 2004 Douglas
+ C. Schmidt <schmidt@ace.cs.wustl.edu>" actually broke
+ ACE_Auto_Event. The idea behind the said checkin was to do a
+ check whether a proper event occured during event_wait (),
+ insted of a spurious wakeup call. This was achieved by checking
+ the value of is_signaled_. This works great for manual
+ events. For auto events, we don't set the variable value if we
+ have waiting threads. This makes the threads calling
+ Auto_Event.wait () to wait for ever.
+
+ We now have another special boolean variable added to
+ ACE_event_t class which keeps track whether an auto event was
+ signalled during the signal () call. Thanks to Dr. Schmidt for
+ giving this idea. We need to revisit this later after x.4 and
+ use inheritance and polymorphism to encapsulate these behvioral
+ differences. Doing now could break backward compatibility.
+
Wed Jan 7 13:03:06 2004 Chad Elliott <elliott_c@ociweb.com>
* bin/MakeProjectCreator/modules/ProjectCreator.pm:
diff --git a/ace/OS_NS_Thread.h b/ace/OS_NS_Thread.h
index 4f05a889eeb..39827f52f41 100644
--- a/ace/OS_NS_Thread.h
+++ b/ace/OS_NS_Thread.h
@@ -1796,6 +1796,16 @@ protected:
/// "True" if signaled.
int is_signaled_;
+ /// Special bool for auto_events alone
+ /**
+ * The semantics of auto events forces us to introduce this extra
+ * variable to ensure that the thread is not woken up
+ * spuriously. Please see event_wait and event_timedwait () to see
+ * how this is used for auto_events. Theoretically this is a hack
+ * that needs revisiting after x.4
+ */
+ bool auto_event_signaled_;
+
/// Number of waiting threads.
unsigned long waiting_threads_;
};
diff --git a/ace/OS_NS_Thread.inl b/ace/OS_NS_Thread.inl
index 43ac7721171..cffd954a27b 100644
--- a/ace/OS_NS_Thread.inl
+++ b/ace/OS_NS_Thread.inl
@@ -819,6 +819,7 @@ ACE_OS::event_init (ACE_event_t *event,
ACE_UNUSED_ARG (sa);
event->manual_reset_ = manual_reset;
event->is_signaled_ = initial_state;
+ event->auto_event_signaled_ = false;
event->waiting_threads_ = 0;
int result = ACE_OS::cond_init (&event->condition_,
@@ -937,6 +938,7 @@ ACE_OS::event_reset (ACE_event_t *event)
{
// Reset event.
event->is_signaled_ = 0;
+ event->auto_event_signaled_ = false;
// Now we can let go of the lock.
ACE_OS::mutex_unlock (&event->lock_);
@@ -965,14 +967,15 @@ ACE_OS::event_signal (ACE_event_t *event)
// Manual-reset event.
if (event->manual_reset_ == 1)
{
- // signal event
- event->is_signaled_ = 1;
// wakeup all
if (ACE_OS::cond_broadcast (&event->condition_) != 0)
{
result = -1;
error = errno;
}
+
+ // signal event
+ event->is_signaled_ = 1;
}
// Auto-reset event
else
@@ -980,13 +983,14 @@ ACE_OS::event_signal (ACE_event_t *event)
if (event->waiting_threads_ == 0)
// No waiters: signal event.
event->is_signaled_ = 1;
-
// Waiters: wakeup one waiter.
else if (ACE_OS::cond_signal (&event->condition_) != 0)
{
result = -1;
error = errno;
}
+
+ event->auto_event_signaled_ = true;
}
// Now we can let go of the lock.
@@ -1072,8 +1076,11 @@ ACE_OS::event_timedwait (ACE_event_t *event,
// event is currently signaled
{
if (event->manual_reset_ == 0)
- // AUTO: reset state
- event->is_signaled_ = 0;
+ {
+ // AUTO: reset state
+ event->is_signaled_ = 0;
+ event->auto_event_signaled_ = false;
+ }
}
else
// event is currently not signaled
@@ -1087,15 +1094,23 @@ ACE_OS::event_timedwait (ACE_event_t *event,
if (use_absolute_time == 0)
absolute_timeout += ACE_OS::gettimeofday ();
- while (event->is_signaled_ == 0)
- if (ACE_OS::cond_timedwait (&event->condition_,
- &event->lock_,
- &absolute_timeout) != 0)
- {
- result = -1;
- error = errno;
- break;
- }
+ while (event->is_signaled_ == 0 &&
+ event->auto_event_signaled_ == false)
+ {
+ if (ACE_OS::cond_timedwait (&event->condition_,
+ &event->lock_,
+ &absolute_timeout) != 0)
+ {
+ result = -1;
+ error = errno;
+ break;
+ }
+ }
+
+ // Reset the auto_event_signaled_ to false now that we have
+ // woken up.
+ if (event->auto_event_signaled_ == true)
+ event->auto_event_signaled_ = false;
event->waiting_threads_--;
}
@@ -1148,15 +1163,22 @@ ACE_OS::event_wait (ACE_event_t *event)
{
event->waiting_threads_++;
- while (event->is_signaled_ == 0)
- if (ACE_OS::cond_wait (&event->condition_,
- &event->lock_) != 0)
- {
- result = -1;
- error = errno;
- // Something went wrong...
- break;
+ while (event->is_signaled_ == 0 &&
+ event->auto_event_signaled_ == false)
+ {
+ if (ACE_OS::cond_wait (&event->condition_,
+ &event->lock_) != 0)
+ {
+ result = -1;
+ error = errno;
+ // Something went wrong...
+ break;
}
+ }
+
+ // Reset it since we have woken up.
+ if (event->auto_event_signaled_ == true)
+ event->auto_event_signaled_ = false;
event->waiting_threads_--;
}