Revision: 8300
http://playerstage.svn.sourceforge.net/playerstage/?rev=8300&view=rev
Author: thjc
Date: 2009-10-18 14:05:50 +0000 (Sun, 18 Oct 2009)
Log Message:
-----------
Applied patch 2859118: Add a timeout to a request from a driver
Modified Paths:
--------------
code/player/trunk/libplayercore/device.cc
code/player/trunk/libplayercore/device.h
Modified: code/player/trunk/libplayercore/device.cc
===================================================================
--- code/player/trunk/libplayercore/device.cc 2009-10-18 13:50:43 UTC (rev
8299)
+++ code/player/trunk/libplayercore/device.cc 2009-10-18 14:05:50 UTC (rev
8300)
@@ -238,7 +238,19 @@
double* timestamp,
bool threaded)
{
- // Send the request message
+ return this->TimedRequest(resp_queue, type, subtype, src, 0, timestamp,
threaded);
+}
+
+Message*
+Device::TimedRequest(QueuePointer &resp_queue,
+ uint8_t type,
+ uint8_t subtype,
+ void* src,
+ double timeout,
+ double* timestamp,
+ bool threaded)
+{
+ // Send the request message
this->PutMsg(resp_queue,
type, subtype,
src, 0, timestamp);
@@ -262,13 +274,38 @@
// non-threaded, then his ProcessMessage() would get called
// recursively).
+
+ // If the timeout is larger than zero it will wait for that long before
returning and it will
+ // return NULL after clearing the filter
+
Message* msg = NULL;
if(threaded)
{
// test driver is still subscribed to prevent deadlocks on server shutdown
while(driver->HasSubscriptions())
{
- resp_queue->Wait(1);
+ // No timeout
+ if (timeout <= 0)
+ resp_queue->Wait(1);
+ // Timeout will less than a second to go
+ else if (timeout <= 1)
+ {
+ if (!resp_queue->Wait(timeout))
+ {
+ // if false is returned it means that a timeout occurred, hence we
shoudl return NULL
+ PLAYER_WARN("Timed out on a request");
+ resp_queue->ClearFilter();
+ return NULL;
+ }
+ }
+ // There is over a second to go, so wait a second and then decrement
timeout
+ // Need to only wait one second as must still wake to check has
subscriptions
+ else
+ {
+ resp_queue->Wait(1);
+ timeout -= 1;
+ }
+
msg = resp_queue->Pop();
// a message is not the only reason a thread can be woken up, so
continue to loop if we didn't get a message
if (msg)
@@ -277,6 +314,9 @@
}
else
{
+ double req_time, curr_time;
+ GlobalTime->GetTimeDouble(&req_time);
+
for(;;)
{
// We don't lock here, on the assumption that the caller is also the only
@@ -295,6 +335,17 @@
if((msg = resp_queue->Pop()))
break;
+
+ if (timeout > 0)
+ {
+ GlobalTime->GetTimeDouble(&curr_time);
+ if (curr_time > req_time + timeout)
+ {
+ PLAYER_WARN("Timed out on a non-threaded request");
+ resp_queue->ClearFilter();
+ return NULL;
+ }
+ }
}
}
Modified: code/player/trunk/libplayercore/device.h
===================================================================
--- code/player/trunk/libplayercore/device.h 2009-10-18 13:50:43 UTC (rev
8299)
+++ code/player/trunk/libplayercore/device.h 2009-10-18 14:05:50 UTC (rev
8300)
@@ -156,6 +156,42 @@
size_t deprecated,
double* timestamp,
bool threaded = true);
+
+ /// @brief Make a request of another device with a timeout.
+ ///
+ /// This method send a request message to a device
+ /// and waits for the reply. If a timeout occurs it returns NULL.
+ ///
+ /// Note that any driver calling this here a timeout is not going to be a
bad error also
+ /// needs to add into its process messages somethig to handle the ACKs if
they are recieved
+ /// after the timeout. As such I would recomment that this is only called
with a timeout not
+ /// 0 if a timeout occurring is an indicaion of a system ailure (and a
stall is unacceptable)
+ ///
+ /// @param resp_queue : Where to push the reply (e.g., your InQueue)
+ /// @param type : Message type (usually PLAYER_MSGTYPE_REQ).
+ /// @param subtype : Message subtype (interface-specific)
+ /// @param src : Message body
+ /// @param timeout: How long to wait for a response, if zero will never
timeout
+ /// @param timestamp : If non-NULL, the timestamp to attach to the
+ /// request; otherwise, the current time is filled in.
+ /// @param threaded : True if the caller is executing in its own
+ /// thread, false otherwise
+ ///
+ /// @note It is is crucial that @p threaded be set correctly. If you
+ /// call this method from within Setup() or Shutdown(), or if
+ /// your driver does not run in its own thread, then @p
+ /// threaded must be false. Deadlocks will otherwise result.
+ ///
+ /// @returns A pointer to the reply message. The caller is responsible
+ /// for deleting this pointer. Will return NULL on a failure
+ Message* TimedRequest(QueuePointer &resp_queue,
+ uint8_t type,
+ uint8_t subtype,
+ void* src,
+ double timeout = 0,
+ double* timestamp = NULL,
+ bool threaded = true);
+
/// @brief Compare two addresses
///
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit