summaryrefslogtreecommitdiff
path: root/tests/Future_Test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/Future_Test.cpp')
-rw-r--r--tests/Future_Test.cpp152
1 files changed, 126 insertions, 26 deletions
diff --git a/tests/Future_Test.cpp b/tests/Future_Test.cpp
index 6c42e795d08..6bededf0c32 100644
--- a/tests/Future_Test.cpp
+++ b/tests/Future_Test.cpp
@@ -12,8 +12,8 @@
// This example tests the ACE Future.
//
// = AUTHOR
-// Andres Kruse <Andres.Kruse@cern.ch> and Douglas C. Schmidt
-// <schmidt@cs.wustl.edu>
+// Andres Kruse <Andres.Kruse@cern.ch>, Douglas C. Schmidt
+// <schmidt@cs.wustl.edu> and Per Andersson <pera@ipso.se>
//
// ============================================================================
@@ -36,15 +36,12 @@ static ATOMIC_INT task_count (0);
// a counter for the futures..
static ATOMIC_INT future_count (0);
-static ATOMIC_INT future_no (0);
// a counter for the capsules..
static ATOMIC_INT capsule_count (0);
-static ATOMIC_INT capsule_no (0);
// a counter for the method objects...
static ATOMIC_INT methodobject_count (0);
-static ATOMIC_INT methodobject_no (0);
class Scheduler : public ACE_Task<ACE_MT_SYNCH>
// = TITLE
@@ -92,10 +89,10 @@ Method_Object_work::Method_Object_work (Scheduler* new_Scheduler,
u_long new_param,
int new_count,
ACE_Future<u_long> &new_result)
- : scheduler_ (new_Scheduler),
- param_ (new_param),
- count_ (new_count),
- future_result_ (new_result)
+ : scheduler_ (new_Scheduler),
+ param_ (new_param),
+ count_ (new_count),
+ future_result_ (new_result)
{
ACE_DEBUG ((LM_DEBUG,
"(%t) Method_Object_work created\n"));
@@ -103,14 +100,17 @@ Method_Object_work::Method_Object_work (Scheduler* new_Scheduler,
Method_Object_work::~Method_Object_work (void)
{
- ACE_DEBUG ((LM_DEBUG, "(%t) Method_Object_work will be deleted.\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) Method_Object_work will be deleted.\n"));
}
int
Method_Object_work::call (void)
{
- return this->future_result_.set (this->scheduler_->work_i (this->param_, this->count_));
+ return this->future_result_.set
+ (this->scheduler_->work_i (this->param_,
+ this->count_));
}
class Method_Object_name : public ACE_Method_Object
@@ -118,7 +118,8 @@ class Method_Object_name : public ACE_Method_Object
// Reification of the <name> method.
{
public:
- Method_Object_name (Scheduler *, ACE_Future<const char*> &);
+ Method_Object_name (Scheduler *,
+ ACE_Future<const char*> &);
virtual ~Method_Object_name (void);
virtual int call (void);
@@ -153,27 +154,36 @@ class Method_Object_end : public ACE_Method_Object
// Reification of the <end> method.
{
public:
- Method_Object_end (Scheduler *new_Scheduler): scheduler_ (new_Scheduler) {}
+ Method_Object_end (Scheduler *new_Scheduler)
+ : scheduler_ (new_Scheduler) {}
virtual ~Method_Object_end (void) {}
- virtual int call (void) { this->scheduler_->close (); return -1; }
+ virtual int call (void) {
+ this->scheduler_->close ();
+ return -1;
+ }
private:
Scheduler *scheduler_;
};
// constructor
-Scheduler::Scheduler (const char *newname, Scheduler *new_Scheduler)
+Scheduler::Scheduler (const char *newname,
+ Scheduler *new_Scheduler)
{
ACE_NEW (this->name_, char[ACE_OS::strlen (newname) + 1]);
ACE_OS::strcpy ((char *) this->name_, newname);
this->scheduler_ = new_Scheduler;
- ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s created\n", this->name_));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) Scheduler %s created\n",
+ this->name_));
}
// Destructor
Scheduler::~Scheduler (void)
{
- ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s will be destroyed\n", this->name_));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) Scheduler %s will be destroyed\n",
+ this->name_));
delete[] this->name_;
}
@@ -182,7 +192,10 @@ int
Scheduler::open (void *)
{
task_count++;
- ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s open\n", this->name_));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) Scheduler %s open\n",
+ this->name_));
+ // Become an Active Object.
return this->activate (THR_BOUND);
}
@@ -190,7 +203,9 @@ Scheduler::open (void *)
int
Scheduler::close (u_long)
{
- ACE_DEBUG ((LM_DEBUG, "(%t) Scheduler %s close\n", this->name_));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) Scheduler %s close\n",
+ this->name_));
task_count--;
return 0;
}
@@ -269,7 +284,8 @@ Scheduler::work (u_long newparam, int newcount)
ACE_Future<u_long> new_future;
this->activation_queue_.enqueue
- (new Method_Object_work (this, newparam, newcount, new_future));
+ (new Method_Object_work (this, newparam,
+ newcount, new_future));
return new_future;
}
}
@@ -281,10 +297,12 @@ static int n_loops = 100;
#if defined (ACE_TEMPLATES_REQUIRE_SPECIALIZATION)
template class ACE_Future<const char *>;
+template class ACE_Future<int>;
template class ACE_Future<u_long>;
-template class auto_ptr<ACE_Method_Object>;
template class ACE_Future_Rep<char const *>;
-template class ACE_Future_Rep<unsigned long>;
+template class ACE_Future_Rep<int>;
+template class ACE_Future_Rep<u_long>;
+template class auto_ptr<ACE_Method_Object>;
#endif /* ACE_TEMPLATES_REQUIRE_SPECIALIZATION */
#endif /* ACE_HAS_THREADS */
@@ -317,7 +335,8 @@ main (int, char *[])
ACE_Future<u_long> fresulta, fresultb, fresultc, fresultd, fresulte;
ACE_Future<const char*> fname;
- ACE_DEBUG ((LM_DEBUG, "(%t) going to do a non-blocking call\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) going to do a non-blocking call\n"));
fresulta = andres->work (9013);
fresultb = peter->work (9013);
@@ -327,9 +346,11 @@ main (int, char *[])
// see if the result is available...
if (fresulta.ready ())
- ACE_DEBUG ((LM_DEBUG, "(%t) wow.. work is ready.....\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) wow.. work is ready.....\n"));
- ACE_DEBUG ((LM_DEBUG, "(%t) non-blocking call done... now blocking...\n"));
+ ACE_DEBUG ((LM_DEBUG,
+ "(%t) non-blocking call done... now blocking...\n"));
// Save the result of fresulta.
@@ -390,7 +411,86 @@ main (int, char *[])
(int) capsule_count,
(int) methodobject_count));
- ACE_DEBUG ((LM_DEBUG,"(%t) th' that's all folks!\n"));
+ {
+ // Check if set then get works, older versions of ACE_Future
+ // will lock forever (or until the timer expires), will use a small
+ // timer value to avoid blocking the process.
+
+ ACE_Future<int> f1;
+ f1.set(100);
+
+ ACE_Time_Value timeout(1);
+ int value = 0;
+
+ if (f1.get (value, &timeout) == 0 && value == 100)
+ ACE_DEBUG ((LM_DEBUG,
+ "Ace_Future<T>::Set followed by Ace_Future<T>::Get works.\n"));
+ else
+ ACE_DEBUG ((LM_DEBUG,
+ "ACE_Future<T>::Set followed by Ace_Future<T>::Get does "
+ "not work, broken Ace_Future<> implementation.\n"));
+ }
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "Checking if Ace_Future<T>::operator= is implemented "
+ "incorrectly this might crash the program.\n"));
+
+ ACE_Future<int> f1;
+ {
+ ACE_Future<int> f2 (f1); // To ensure that a rep object is created
+ }
+ // Now it is one ACE_Future<int> referencing the rep instance
+
+ ACE_DEBUG ((LM_DEBUG, "0.\n"));
+ //check that self assignment works
+ f1 = f1;
+ // Is there any repesentation left, and if so what is the ref
+ // count older ACE_Future<> implementations have deleted the rep
+ // instance at this moment
+
+ // The stuff below might crash the process if the op=
+ // implementation was bad
+ int value = 0;
+ ACE_Time_Value timeout (1);
+
+ f1.set (100);
+ f1.get (value, &timeout);
+
+ ACE_DEBUG ((LM_DEBUG, "1.\n"));
+ { // Might delete the same data a couple of times
+ ACE_Future<int> f2 (f1);
+ f1.set (100);
+ f1.get (value, &timeout);
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "2.\n"));
+ {
+ ACE_Future<int> f2 (f1);
+ f1.set (100);
+ f1.get (value, &timeout);
+ }
+
+ ACE_DEBUG ((LM_DEBUG, "3.\n"));
+ {
+ ACE_Future<int> f2 (f1);
+ f1.set (100);
+ f1.get (value, &timeout);
+ }
+ ACE_DEBUG ((LM_DEBUG, "4.\n"));
+ {
+ ACE_Future<int> f2 (f1);
+ f1.set (100);
+ f1.get (value, &timeout);
+ }
+ ACE_DEBUG ((LM_DEBUG, "5.\n"));
+ {
+ ACE_Future<int> f2 (90);
+ f2.get (value, &timeout);
+ f1.get (value, &timeout);
+ }
+ }
+ ACE_DEBUG ((LM_DEBUG,
+ "No it did not crash the program.\n"));
ACE_OS::sleep (5);