started on documentation and changes to misc as a result
This commit is contained in:
@@ -23,6 +23,7 @@ INC += timer.h
|
||||
|
||||
LIBSRCS += byteBuffer.cpp
|
||||
LIBSRCS += bitSet.cpp
|
||||
LIBSRCS += requester.cpp
|
||||
LIBSRCS += serializeHelper.cpp
|
||||
LIBSRCS += showConstructDestruct.cpp
|
||||
LIBSRCS += linkedListVoid.cpp
|
||||
|
||||
@@ -12,10 +12,6 @@
|
||||
//#include "serialize.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
// TODO !!!
|
||||
typedef unsigned long long uint64;
|
||||
typedef std::string * StringBuilder;
|
||||
|
||||
/**
|
||||
* This class implements a vector of bits that grows as needed. Each
|
||||
* component of the bit set has a {@code bool} value. The
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
@@ -56,13 +57,17 @@ static void init()
|
||||
|
||||
Event::~Event() {
|
||||
epicsEventDestroy(id);
|
||||
id = 0;
|
||||
Lock xx(globalMutex);
|
||||
totalDestruct++;
|
||||
}
|
||||
|
||||
Event::Event(EventInitialState initial)
|
||||
: id(epicsEventCreate((initial==eventEmpty)?epicsEventEmpty : epicsEventFull))
|
||||
|
||||
Event::Event(bool full)
|
||||
: id(epicsEventCreate(full?epicsEventFull : epicsEventEmpty))
|
||||
{
|
||||
init();
|
||||
Lock xx(globalMutex);
|
||||
totalConstruct++;
|
||||
}
|
||||
|
||||
@@ -74,23 +79,27 @@ ConstructDestructCallback *Event::getConstructDestructCallback()
|
||||
|
||||
void Event::signal()
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
epicsEventSignal(id);
|
||||
}
|
||||
|
||||
bool Event::wait ()
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
epicsEventWaitStatus status = epicsEventWait(id);
|
||||
return status==epicsEventWaitOK ? true : false;
|
||||
}
|
||||
|
||||
bool Event::wait ( double timeOut )
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
epicsEventWaitStatus status = epicsEventWaitWithTimeout(id,timeOut);
|
||||
return status==epicsEventWaitOK ? true : false;
|
||||
}
|
||||
|
||||
bool Event::tryWait ()
|
||||
{
|
||||
if(id==0) throw std::logic_error(String("event was deleted"));
|
||||
epicsEventWaitStatus status = epicsEventTryWait(id);
|
||||
return status==epicsEventWaitOK ? true : false;
|
||||
}
|
||||
|
||||
+1
-13
@@ -16,22 +16,10 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
enum EventWaitStatus {
|
||||
eventWaitOK,
|
||||
eventWaitTimeout,
|
||||
eventWaitError
|
||||
};
|
||||
|
||||
enum EventInitialState {
|
||||
eventEmpty,
|
||||
eventFull
|
||||
};
|
||||
|
||||
|
||||
class Event : private NoDefaultMethods {
|
||||
public:
|
||||
explicit Event(bool = false);
|
||||
~Event();
|
||||
Event(EventInitialState initial);
|
||||
static ConstructDestructCallback *getConstructDestructCallback();
|
||||
void signal();
|
||||
bool wait (); /* blocks until full */
|
||||
|
||||
+17
-39
@@ -81,14 +81,13 @@ ConstructDestructCallback *Executor::getConstructDestructCallback()
|
||||
return pConstructDestructCallback;
|
||||
}
|
||||
|
||||
class ExecutorPvt : public RunnableReady {
|
||||
class ExecutorPvt : public Runnable{
|
||||
public:
|
||||
ExecutorPvt(String threadName,ThreadPriority priority);
|
||||
~ExecutorPvt();
|
||||
ExecutorNode * createNode(Command *command);
|
||||
void execute(ExecutorNode *node);
|
||||
void destroy();
|
||||
virtual void run(ThreadReady *threadReady);
|
||||
virtual void run();
|
||||
private:
|
||||
ExecutorList *executorList;
|
||||
ExecutorList *runList;
|
||||
@@ -102,37 +101,39 @@ private:
|
||||
ExecutorPvt::ExecutorPvt(String threadName,ThreadPriority priority)
|
||||
: executorList(new ExecutorList()),
|
||||
runList(new ExecutorList()),
|
||||
moreWork(new Event(eventEmpty)),
|
||||
stopped(new Event(eventEmpty)),
|
||||
moreWork(new Event(false)),
|
||||
stopped(new Event(false)),
|
||||
mutex(Mutex()),
|
||||
alive(true),
|
||||
thread(new Thread(threadName,priority,this))
|
||||
{
|
||||
thread->start();
|
||||
}
|
||||
{}
|
||||
|
||||
ExecutorPvt::~ExecutorPvt()
|
||||
{
|
||||
{
|
||||
Lock xx(&mutex);
|
||||
alive = false;
|
||||
}
|
||||
moreWork->signal();
|
||||
{
|
||||
Lock xx(&mutex);
|
||||
stopped->wait();
|
||||
}
|
||||
ExecutorListNode *node;
|
||||
while((node=executorList->removeHead())!=0) {
|
||||
delete node->getObject();
|
||||
}
|
||||
delete thread;
|
||||
delete stopped;
|
||||
delete moreWork;
|
||||
delete runList;
|
||||
delete executorList;
|
||||
delete thread;
|
||||
}
|
||||
|
||||
void ExecutorPvt::run(ThreadReady *threadReady)
|
||||
void ExecutorPvt::run()
|
||||
{
|
||||
bool firstTime = true;
|
||||
while(alive) {
|
||||
ExecutorListNode * executorListNode = 0;
|
||||
if(firstTime) {
|
||||
firstTime = false;
|
||||
threadReady->ready();
|
||||
}
|
||||
while(alive && runList->isEmpty()) {
|
||||
moreWork->wait();
|
||||
}
|
||||
@@ -164,20 +165,6 @@ void ExecutorPvt::execute(ExecutorNode *node)
|
||||
if(isEmpty) moreWork->signal();
|
||||
}
|
||||
|
||||
void ExecutorPvt::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(&mutex);
|
||||
alive = false;
|
||||
}
|
||||
moreWork->signal();
|
||||
{
|
||||
Lock xx(&mutex);
|
||||
stopped->wait();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
Executor::Executor(String threadName,ThreadPriority priority)
|
||||
: pImpl(new ExecutorPvt(threadName,priority))
|
||||
{
|
||||
@@ -187,23 +174,14 @@ Executor::Executor(String threadName,ThreadPriority priority)
|
||||
}
|
||||
|
||||
Executor::~Executor() {
|
||||
delete pImpl;
|
||||
Lock xx(globalMutex);
|
||||
totalDestruct++;
|
||||
}
|
||||
|
||||
Executor *Executor::create(String threadName,ThreadPriority priority)
|
||||
{
|
||||
return new Executor(threadName,priority);
|
||||
}
|
||||
|
||||
ExecutorNode * Executor::createNode(Command*command)
|
||||
{return pImpl->createNode(command);}
|
||||
|
||||
void Executor::execute(ExecutorNode *node) {pImpl->execute(node);}
|
||||
void Executor::destroy() {
|
||||
pImpl->destroy();
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -24,14 +24,12 @@ public:
|
||||
|
||||
class Executor : private NoDefaultMethods {
|
||||
public:
|
||||
static ConstructDestructCallback *getConstructDestructCallback();
|
||||
static Executor *create(String threadName,ThreadPriority priority);
|
||||
ExecutorNode * createNode(Command *command);
|
||||
void execute(ExecutorNode *node);
|
||||
void destroy();
|
||||
private:
|
||||
Executor(String threadName,ThreadPriority priority);
|
||||
~Executor();
|
||||
static ConstructDestructCallback *getConstructDestructCallback();
|
||||
ExecutorNode * createNode(Command *command);
|
||||
void execute(ExecutorNode *node);
|
||||
private:
|
||||
class ExecutorPvt *pImpl;
|
||||
};
|
||||
|
||||
|
||||
+18
-15
@@ -17,8 +17,9 @@ class LinkedListNode : private LinkedListVoidNode {
|
||||
public:
|
||||
LinkedListNode(T *object) : LinkedListVoidNode(object){}
|
||||
~LinkedListNode() {}
|
||||
T *getObject() { return (T *)LinkedListVoidNode::getObject();}
|
||||
T *getObject() { return static_cast<T *>(LinkedListVoidNode::getObject());}
|
||||
bool isOnList() {return LinkedListVoidNode::isOnList();}
|
||||
friend class LinkedList<T>;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@@ -29,49 +30,51 @@ public:
|
||||
int getLength() {return LinkedListVoid::getLength();}
|
||||
void addTail(LinkedListNode<T> *listNode)
|
||||
{
|
||||
LinkedListVoid::addTail((LinkedListVoidNode *)listNode);
|
||||
LinkedListVoid::addTail(static_cast<LinkedListVoidNode *>(listNode));
|
||||
}
|
||||
void addHead(LinkedListNode<T> *listNode)
|
||||
{
|
||||
LinkedListVoid::addHead((LinkedListVoidNode *)listNode);
|
||||
LinkedListVoid::addHead(static_cast<LinkedListVoidNode *>(listNode));
|
||||
}
|
||||
void insertAfter(LinkedListNode<T> *listNode,
|
||||
LinkedListNode<T> *addNode)
|
||||
{
|
||||
LinkedListVoid::insertAfter(
|
||||
(LinkedListVoidNode *)listNode,(LinkedListVoidNode *)addNode);
|
||||
static_cast<LinkedListVoidNode *>(listNode),
|
||||
static_cast<LinkedListVoidNode *>(addNode));
|
||||
}
|
||||
void insertBefore(LinkedListNode<T> *listNode,
|
||||
LinkedListNode<T> *addNode)
|
||||
{
|
||||
LinkedListVoid::insertBefore((LinkedListVoidNode *)listNode,
|
||||
(LinkedListVoidNode *)addNode);
|
||||
LinkedListVoid::insertBefore(
|
||||
static_cast<LinkedListVoidNode *>(listNode),
|
||||
static_cast<LinkedListVoidNode *>(addNode));
|
||||
}
|
||||
LinkedListNode<T> *removeTail(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::removeTail();
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::removeTail());
|
||||
}
|
||||
LinkedListNode<T> *removeHead(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::removeHead();
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::removeHead());
|
||||
}
|
||||
void remove(LinkedListNode<T> *listNode){
|
||||
LinkedListVoid::remove((LinkedListVoidNode *)listNode);
|
||||
LinkedListVoid::remove(static_cast<LinkedListVoidNode *>(listNode));
|
||||
}
|
||||
void remove(T *object){
|
||||
LinkedListVoid::remove(object);
|
||||
}
|
||||
LinkedListNode<T> *getHead(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getHead();
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getHead());
|
||||
}
|
||||
LinkedListNode<T> *getTail(){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getTail();
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getTail());
|
||||
}
|
||||
LinkedListNode<T> *getNext(LinkedListNode<T> *listNode){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getNext(
|
||||
(LinkedListVoidNode *)listNode);
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getNext(
|
||||
static_cast<LinkedListVoidNode *>(listNode)));
|
||||
}
|
||||
LinkedListNode<T> *getPrev(LinkedListNode<T> *listNode){
|
||||
return (LinkedListNode<T>*)LinkedListVoid::getPrev(
|
||||
(LinkedListVoidNode *)listNode);
|
||||
return static_cast<LinkedListNode<T> *>(LinkedListVoid::getPrev(
|
||||
static_cast<LinkedListVoidNode *>(listNode)));
|
||||
}
|
||||
bool isEmpty() { return LinkedListVoid::isEmpty();}
|
||||
bool contains(T *object) { return LinkedListVoid::contains(object);}
|
||||
|
||||
@@ -69,7 +69,7 @@ static void initPvt()
|
||||
|
||||
|
||||
LinkedListVoidNode::LinkedListVoidNode(void *object)
|
||||
: object(object),before(0),after(0)
|
||||
: object(object),before(0),after(0),linkedListVoid(0)
|
||||
{
|
||||
initPvt();
|
||||
Lock xx(globalMutex);
|
||||
@@ -138,6 +138,7 @@ void LinkedListVoid::addTail(LinkedListVoidNode *node)
|
||||
if(node->before!=0 || node->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node->linkedListVoid = this;
|
||||
node->before = head->before;
|
||||
node->after = head;
|
||||
head->before->after = node;
|
||||
@@ -150,6 +151,7 @@ void LinkedListVoid::addHead(LinkedListVoidNode *node)
|
||||
if(node->before!=0 || node->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
node->linkedListVoid = this;
|
||||
node->after = head->after;
|
||||
node->before = head;
|
||||
head->after->before = node;
|
||||
@@ -168,6 +170,10 @@ void LinkedListVoid::insertAfter(LinkedListVoidNode *node,
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
if(node->linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
newNode->linkedListVoid = this;
|
||||
newNode->after = existingNode->after;
|
||||
newNode->before = existingNode;
|
||||
existingNode->after->before = newNode;
|
||||
@@ -186,6 +192,10 @@ void LinkedListVoid::insertBefore(LinkedListVoidNode *node,
|
||||
if(newNode->before!=0 || newNode->after!=0) {
|
||||
throw std::logic_error(alreadyOnList);
|
||||
}
|
||||
if(node->linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
newNode->linkedListVoid = this;
|
||||
newNode->after = existingNode;
|
||||
newNode->before = existingNode->before;
|
||||
existingNode->before->after = newNode;
|
||||
@@ -209,12 +219,15 @@ LinkedListVoidNode *LinkedListVoid::removeHead()
|
||||
return node;
|
||||
}
|
||||
|
||||
void LinkedListVoid::remove(LinkedListVoidNode *listNode)
|
||||
void LinkedListVoid::remove(LinkedListVoidNode *node)
|
||||
{
|
||||
LinkedListVoidNode *node = listNode;
|
||||
if(node->before==0 || node->after==0) {
|
||||
throw std::logic_error(String("listNode not on list"));
|
||||
throw std::logic_error(String("node not on list"));
|
||||
}
|
||||
if(node->linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
node->linkedListVoid = 0;
|
||||
LinkedListVoidNode *prev = node->before;
|
||||
LinkedListVoidNode *next = node->after;
|
||||
node->after = node->before = 0;
|
||||
@@ -233,6 +246,7 @@ void LinkedListVoid::remove(void * object)
|
||||
}
|
||||
node = getNext(node);
|
||||
}
|
||||
throw std::logic_error(String("object not on this list"));
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getHead()
|
||||
@@ -249,12 +263,18 @@ LinkedListVoidNode *LinkedListVoid::getTail()
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getNext(LinkedListVoidNode *listNode)
|
||||
{
|
||||
if(listNode->linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
if(listNode->after==head) return 0;
|
||||
return listNode->after;
|
||||
}
|
||||
|
||||
LinkedListVoidNode *LinkedListVoid::getPrev(LinkedListVoidNode *listNode)
|
||||
{
|
||||
if(listNode->linkedListVoid!=this) {
|
||||
throw std::logic_error(String("node not on this list"));
|
||||
}
|
||||
if(listNode->before==head) return 0;
|
||||
return listNode->before;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ private:
|
||||
void *object;
|
||||
LinkedListVoidNode *before;
|
||||
LinkedListVoidNode *after;
|
||||
LinkedListVoid *linkedListVoid;
|
||||
// do not implement the following
|
||||
LinkedListVoidNode(const LinkedListVoidNode&);
|
||||
LinkedListVoidNode & operator=(const LinkedListVoidNode&);
|
||||
|
||||
+18
-18
@@ -14,25 +14,25 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex() : id(epicsMutexMustCreate()){}
|
||||
~Mutex() { epicsMutexDestroy(id) ;};
|
||||
void lock(){epicsMutexMustLock(id);}\
|
||||
void unlock(){epicsMutexUnlock(id);}
|
||||
private:
|
||||
epicsMutexId id;
|
||||
};
|
||||
class Mutex {
|
||||
public:
|
||||
Mutex() : id(epicsMutexMustCreate()){}
|
||||
~Mutex() { epicsMutexDestroy(id) ;}
|
||||
void lock(){epicsMutexMustLock(id);}
|
||||
void unlock(){epicsMutexUnlock(id);}
|
||||
private:
|
||||
epicsMutexId id;
|
||||
};
|
||||
|
||||
|
||||
class Lock : private NoDefaultMethods {
|
||||
public:
|
||||
explicit Lock(Mutex *pm)
|
||||
: mutexPtr(pm)
|
||||
{mutexPtr->lock();}
|
||||
~Lock(){mutexPtr->unlock();}
|
||||
private:
|
||||
Mutex *mutexPtr;
|
||||
};
|
||||
class Lock : private NoDefaultMethods {
|
||||
public:
|
||||
explicit Lock(Mutex *pm)
|
||||
: mutexPtr(pm)
|
||||
{mutexPtr->lock();}
|
||||
~Lock(){mutexPtr->unlock();}
|
||||
private:
|
||||
Mutex *mutexPtr;
|
||||
};
|
||||
}}
|
||||
#endif /* LOCK_H */
|
||||
|
||||
@@ -10,16 +10,16 @@
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
typedef signed char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
typedef long long int64;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long uint64;
|
||||
typedef signed char int8;
|
||||
typedef short int16;
|
||||
typedef int int32;
|
||||
typedef long long int64;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
typedef std::string String;
|
||||
typedef std::string * StringBuilder;
|
||||
typedef String* StringArray;
|
||||
typedef std::string String;
|
||||
typedef std::string * StringBuilder;
|
||||
typedef String* StringArray;
|
||||
|
||||
}}
|
||||
#endif /* PVTYPE_H */
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/* requester.cpp */
|
||||
/**
|
||||
* Copyright - See the COPYRIGHT that is included with this distribution.
|
||||
* EPICS pvDataCPP is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
*/
|
||||
#include <string>
|
||||
#include "requester.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
static std::string typeName[] = {
|
||||
String("info"),
|
||||
String("warning"),
|
||||
String("error"),
|
||||
String("fatalError")
|
||||
};
|
||||
|
||||
StringArray messageTypeName = typeName;
|
||||
|
||||
}}
|
||||
+13
-15
@@ -7,24 +7,22 @@
|
||||
#include <string>
|
||||
#ifndef REQUESTER_H
|
||||
#define REQUESTER_H
|
||||
#include "pvIntrospect.h"
|
||||
#include "pvType.h"
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
class Requester;
|
||||
|
||||
enum MessageType {
|
||||
infoMessage,warningMessage,errorMessage,fatalErrorMessage
|
||||
};
|
||||
class Requester;
|
||||
|
||||
static std::string messageTypeName[] = {
|
||||
"info","warning","error","fatalError"
|
||||
};
|
||||
|
||||
class Requester {
|
||||
public:
|
||||
virtual String getRequesterName() = 0;
|
||||
virtual void message(String message,MessageType messageType) = 0;
|
||||
};
|
||||
enum MessageType {
|
||||
infoMessage,warningMessage,errorMessage,fatalErrorMessage
|
||||
};
|
||||
|
||||
extern StringArray messageTypeName;
|
||||
|
||||
class Requester {
|
||||
public:
|
||||
virtual String getRequesterName() = 0;
|
||||
virtual void message(String message,MessageType messageType) = 0;
|
||||
};
|
||||
|
||||
}}
|
||||
#endif /* REQUESTER_H */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "noDefaultMethods.h"
|
||||
#include "lock.h"
|
||||
@@ -62,6 +63,7 @@ ShowConstructDestruct::ShowConstructDestruct() {}
|
||||
|
||||
void ShowConstructDestruct::constuctDestructTotals(FILE *fd)
|
||||
{
|
||||
getShowConstructDestruct(); // make it initialize
|
||||
Lock xx(globalMutex);
|
||||
ListNode *node = list->getHead();
|
||||
while(node!=0) {
|
||||
@@ -80,8 +82,33 @@ void ShowConstructDestruct::constuctDestructTotals(FILE *fd)
|
||||
|
||||
void ShowConstructDestruct::registerCallback(ConstructDestructCallback *callback)
|
||||
{
|
||||
static ConstructDestructCallback *listCallback = 0;
|
||||
static ConstructDestructCallback *listNodeCallback = 0;
|
||||
Lock xx(globalMutex);
|
||||
ListNode *listNode = new ListNode(callback);
|
||||
ListNode *listNode = 0;
|
||||
if(list==0) {
|
||||
if(callback->getConstructName().compare("linkedListNode")==0) {
|
||||
listNodeCallback = callback;
|
||||
} else if(callback->getConstructName().compare("linkedList")==0) {
|
||||
listCallback = callback;
|
||||
} else {
|
||||
throw std::logic_error(String("ShowConstructDestruct::registerCallback"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(listCallback!=0) {
|
||||
if(listNodeCallback==0) {
|
||||
throw std::logic_error(String(
|
||||
"ShowConstructDestruct::registerCallback expected listNodeCallback!=0"));
|
||||
}
|
||||
listNode = new ListNode(listNodeCallback);
|
||||
list->addTail(listNode);
|
||||
listNode = new ListNode(listCallback);
|
||||
list->addTail(listNode);
|
||||
listCallback = 0;
|
||||
listNodeCallback = 0;
|
||||
}
|
||||
listNode = new ListNode(callback);
|
||||
list->addTail(listNode);
|
||||
}
|
||||
|
||||
@@ -91,9 +118,9 @@ ShowConstructDestruct * getShowConstructDestruct()
|
||||
Lock xx(&mutex);
|
||||
if(pShowConstructDestruct==0) {
|
||||
globalMutex = new Mutex();
|
||||
list = new List();
|
||||
pShowConstructDestruct = new ShowConstructDestruct();
|
||||
}
|
||||
list = new List();
|
||||
}
|
||||
return pShowConstructDestruct;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ private:
|
||||
|
||||
class ShowConstructDestruct : private NoDefaultMethods {
|
||||
public:
|
||||
static void constuctDestructTotals(FILE *fd);
|
||||
static void registerCallback(ConstructDestructCallback *callback);
|
||||
void constuctDestructTotals(FILE *fd);
|
||||
void registerCallback(ConstructDestructCallback *callback);
|
||||
private:
|
||||
ShowConstructDestruct();
|
||||
friend ShowConstructDestruct* getShowConstructDestruct();
|
||||
|
||||
+40
-68
@@ -9,6 +9,7 @@
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <epicsThread.h>
|
||||
#include <epicsEvent.h>
|
||||
@@ -48,9 +49,7 @@ typedef LinkedList<ThreadListElement> ThreadList;
|
||||
static volatile int64 totalConstruct = 0;
|
||||
static volatile int64 totalDestruct = 0;
|
||||
static Mutex *globalMutex = 0;
|
||||
static void addThread(Thread *thread);
|
||||
static void removeThread(Thread *thread);
|
||||
static ThreadList *list;
|
||||
static ThreadList *threadList;
|
||||
|
||||
static int64 getTotalConstruct()
|
||||
{
|
||||
@@ -72,7 +71,7 @@ static void init()
|
||||
Lock xx(&mutex);
|
||||
if(globalMutex==0) {
|
||||
globalMutex = new Mutex();
|
||||
list = new ThreadList();
|
||||
threadList = new ThreadList();
|
||||
pConstructDestructCallback = new ConstructDestructCallback(
|
||||
String("thread"),
|
||||
getTotalConstruct,getTotalDestruct,0);
|
||||
@@ -96,38 +95,37 @@ int ThreadPriorityFunc::getEpicsPriority(ThreadPriority threadPriority) {
|
||||
extern "C" void myFunc ( void * pPvt );
|
||||
|
||||
|
||||
class Runnable : public ThreadReady {
|
||||
class ThreadPvt {
|
||||
public:
|
||||
Runnable(Thread *thread,String name,
|
||||
ThreadPriority priority, RunnableReady *runnable);
|
||||
virtual ~Runnable();
|
||||
Thread *start();
|
||||
ThreadPvt(Thread *thread,String name,
|
||||
ThreadPriority priority, Runnable*runnable);
|
||||
virtual ~ThreadPvt();
|
||||
void ready();
|
||||
public: // only used within this source module
|
||||
Thread *thread;
|
||||
String name;
|
||||
ThreadPriority priority;
|
||||
RunnableReady *runnable;
|
||||
Event waitStart;
|
||||
Runnable *runnable;
|
||||
bool isReady;
|
||||
ThreadListElement *threadListElement;
|
||||
Event *waitDone;
|
||||
epicsThreadId id;
|
||||
};
|
||||
|
||||
extern "C" void myFunc ( void * pPvt )
|
||||
{
|
||||
Runnable *runnable = (Runnable *)pPvt;
|
||||
runnable->waitStart.signal();
|
||||
addThread(runnable->thread);
|
||||
runnable->runnable->run(runnable);
|
||||
removeThread(runnable->thread);
|
||||
ThreadPvt *threadPvt = (ThreadPvt *)pPvt;
|
||||
threadPvt->runnable->run();
|
||||
threadPvt->waitDone->signal();
|
||||
}
|
||||
|
||||
Runnable::Runnable(Thread *thread,String name,
|
||||
ThreadPriority priority, RunnableReady *runnable)
|
||||
ThreadPvt::ThreadPvt(Thread *thread,String name,
|
||||
ThreadPriority priority, Runnable *runnable)
|
||||
: thread(thread),name(name),priority(priority),
|
||||
runnable(runnable),
|
||||
waitStart(eventEmpty),
|
||||
isReady(false),
|
||||
threadListElement(new ThreadListElement(thread)),
|
||||
waitDone(new Event()),
|
||||
id(epicsThreadCreate(
|
||||
name.c_str(),
|
||||
epicsPriority[priority],
|
||||
@@ -136,32 +134,35 @@ Runnable::Runnable(Thread *thread,String name,
|
||||
{
|
||||
init();
|
||||
Lock xx(globalMutex);
|
||||
threadList->addTail(threadListElement->node);
|
||||
totalConstruct++;
|
||||
}
|
||||
|
||||
Runnable::~Runnable()
|
||||
ThreadPvt::~ThreadPvt()
|
||||
{
|
||||
bool result = waitDone->wait(2.0);
|
||||
if(!result) {
|
||||
throw std::logic_error(String("delete thread but run did not return"));
|
||||
String message("destroy thread ");
|
||||
message += thread->getName();
|
||||
message += " but run did not return";
|
||||
throw std::logic_error(message);
|
||||
}
|
||||
if(!threadListElement->node->isOnList()) {
|
||||
String message("destroy thread ");
|
||||
message += thread->getName();
|
||||
message += " is not on threadlist";
|
||||
throw std::logic_error(message);
|
||||
}
|
||||
threadList->remove(threadListElement->node);
|
||||
delete waitDone;
|
||||
delete threadListElement;
|
||||
Lock xx(globalMutex);
|
||||
totalDestruct++;
|
||||
}
|
||||
|
||||
|
||||
Thread * Runnable::start()
|
||||
{
|
||||
if(!waitStart.wait(10.0)) {
|
||||
fprintf(stderr,"thread %s did not call ready\n",thread->getName().c_str());
|
||||
}
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
void Runnable::ready()
|
||||
{
|
||||
waitStart.signal();
|
||||
}
|
||||
|
||||
Thread::Thread(String name,ThreadPriority priority,RunnableReady *runnableReady)
|
||||
: pImpl(new Runnable(this,name,priority,runnableReady))
|
||||
Thread::Thread(String name,ThreadPriority priority,Runnable *runnable)
|
||||
: pImpl(new ThreadPvt(this,name,priority,runnable))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -176,12 +177,6 @@ ConstructDestructCallback *Thread::getConstructDestructCallback()
|
||||
return pConstructDestructCallback;
|
||||
}
|
||||
|
||||
void Thread::start()
|
||||
{
|
||||
pImpl->start();
|
||||
}
|
||||
|
||||
|
||||
void Thread::sleep(double seconds)
|
||||
{
|
||||
epicsThreadSleep(seconds);;
|
||||
@@ -201,38 +196,15 @@ void Thread::showThreads(StringBuilder buf)
|
||||
{
|
||||
init();
|
||||
Lock xx(globalMutex);
|
||||
ThreadListNode *node = list->getHead();
|
||||
ThreadListNode *node = threadList->getHead();
|
||||
while(node!=0) {
|
||||
Thread *thread = node->getObject()->thread;
|
||||
*buf += thread->getName();
|
||||
*buf += " ";
|
||||
*buf += threadPriorityNames[thread->getPriority()];
|
||||
*buf += "\n";
|
||||
node = list->getNext(node);
|
||||
node = threadList->getNext(node);
|
||||
}
|
||||
}
|
||||
|
||||
void addThread(Thread *thread)
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
ThreadListElement *element = new ThreadListElement(thread);
|
||||
list->addTail(element->node);
|
||||
}
|
||||
|
||||
void removeThread(Thread *thread)
|
||||
{
|
||||
Lock xx(globalMutex);
|
||||
ThreadListNode *node = list->getHead();
|
||||
while(node!=0) {
|
||||
if(node->getObject()->thread==thread) {
|
||||
list->remove(node);
|
||||
delete node;
|
||||
return;
|
||||
}
|
||||
node = list->getNext(node);
|
||||
}
|
||||
fprintf(stderr,"removeThread but thread %s did not in list\n",
|
||||
thread->getName().c_str());
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
+6
-12
@@ -8,6 +8,7 @@
|
||||
#define THREAD_H
|
||||
#include "noDefaultMethods.h"
|
||||
#include "pvType.h"
|
||||
#include "showConstructDestruct.h"
|
||||
|
||||
namespace epics { namespace pvData {
|
||||
|
||||
@@ -27,32 +28,25 @@ public:
|
||||
static int getEpicsPriority(ThreadPriority threadPriority);
|
||||
};
|
||||
|
||||
|
||||
class ThreadReady {
|
||||
class Runnable{
|
||||
public:
|
||||
virtual void ready() = 0;
|
||||
};
|
||||
|
||||
class RunnableReady {
|
||||
public:
|
||||
virtual void run(ThreadReady *threadReady) = 0;
|
||||
virtual void run() = 0;
|
||||
};
|
||||
|
||||
class Thread;
|
||||
|
||||
class Thread : private NoDefaultMethods {
|
||||
public:
|
||||
Thread(String name,ThreadPriority priority,RunnableReady *runnableReady);
|
||||
Thread(String name,ThreadPriority priority,Runnable *runnable);
|
||||
~Thread();
|
||||
static ConstructDestructCallback *getConstructDestructCallback();
|
||||
void start();
|
||||
String getName();
|
||||
ThreadPriority getPriority();
|
||||
static void showThreads(StringBuilder buf);
|
||||
static void sleep(double seconds);
|
||||
private:
|
||||
class Runnable *pImpl;
|
||||
friend class Runnable;
|
||||
class ThreadPvt *pImpl;
|
||||
friend class ThreadPvt;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -24,8 +24,44 @@ int64 posixEpochAtEpicsEpoch = POSIX_TIME_AT_EPICS_EPOCH;
|
||||
|
||||
TimeStamp::TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds)
|
||||
: secondsPastEpoch(secondsPastEpoch),nanoSeconds(nanoSeconds)
|
||||
{}
|
||||
{
|
||||
normalize();
|
||||
}
|
||||
|
||||
void TimeStamp::normalize()
|
||||
{
|
||||
if(nanoSeconds>=0 && nanoSeconds<nanoSecPerSec) return;
|
||||
while(nanoSeconds>=nanoSecPerSec) {
|
||||
nanoSeconds -= nanoSecPerSec;
|
||||
secondsPastEpoch++;
|
||||
}
|
||||
while(nanoSeconds<0) {
|
||||
nanoSeconds += nanoSecPerSec;
|
||||
secondsPastEpoch--;
|
||||
}
|
||||
}
|
||||
|
||||
void TimeStamp::fromTime_t(const time_t & tt)
|
||||
{
|
||||
epicsTimeStamp epicsTime;
|
||||
epicsTimeFromTime_t(&epicsTime,tt);
|
||||
secondsPastEpoch = epicsTime.secPastEpoch + posixEpochAtEpicsEpoch;
|
||||
nanoSeconds = epicsTime.nsec;
|
||||
}
|
||||
|
||||
void TimeStamp::toTime_t(time_t &tt) const
|
||||
{
|
||||
epicsTimeStamp epicsTime;
|
||||
epicsTime.secPastEpoch = secondsPastEpoch-posixEpochAtEpicsEpoch;
|
||||
epicsTime.nsec = nanoSeconds;
|
||||
epicsTimeToTime_t(&tt,&epicsTime);
|
||||
}
|
||||
|
||||
void TimeStamp::put(int64 milliseconds)
|
||||
{
|
||||
secondsPastEpoch = milliseconds/1000;
|
||||
nanoSeconds = (milliseconds%1000)*1000000;
|
||||
}
|
||||
|
||||
void TimeStamp::getCurrent()
|
||||
{
|
||||
@@ -144,12 +180,4 @@ int64 TimeStamp::getMilliseconds()
|
||||
return secondsPastEpoch*1000 + nanoSeconds/1000000;
|
||||
}
|
||||
|
||||
void TimeStamp::put(int64 milliseconds)
|
||||
{
|
||||
secondsPastEpoch = milliseconds/1000;
|
||||
nanoSeconds = (milliseconds%1000)*1000000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
#ifndef TIMESTAMP_H
|
||||
#define TIMESTAMP_H
|
||||
#include <ctime>
|
||||
#include "epicsTime.h"
|
||||
#include "pvType.h"
|
||||
|
||||
@@ -20,10 +21,12 @@ class TimeStamp {
|
||||
public:
|
||||
TimeStamp()
|
||||
:secondsPastEpoch(0),nanoSeconds(0) {}
|
||||
TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0);
|
||||
//default constructors and destructor are OK
|
||||
//This class should not be extended
|
||||
TimeStamp(int64 secondsPastEpoch,int32 nanoSeconds = 0);
|
||||
TimeStamp(epicsTimeStamp &epics);
|
||||
void normalize();
|
||||
void fromTime_t(const time_t &);
|
||||
void toTime_t(time_t &) const;
|
||||
int64 getSecondsPastEpoch() const {return secondsPastEpoch;}
|
||||
int64 getEpicsSecondsPastEpoch() const {
|
||||
return secondsPastEpoch - posixEpochAtEpicsEpoch;
|
||||
@@ -32,7 +35,9 @@ public:
|
||||
void put(int64 secondsPastEpoch,int32 nanoSeconds = 0) {
|
||||
this->secondsPastEpoch = secondsPastEpoch;
|
||||
this->nanoSeconds = nanoSeconds;
|
||||
normalize();
|
||||
}
|
||||
void put(int64 milliseconds);
|
||||
void getCurrent();
|
||||
double toSeconds() const ;
|
||||
bool operator==(TimeStamp const &) const;
|
||||
@@ -46,10 +51,7 @@ public:
|
||||
TimeStamp & operator-=(int64 seconds);
|
||||
TimeStamp & operator+=(double seconds);
|
||||
TimeStamp & operator-=(double seconds);
|
||||
// milliseconds since epoch
|
||||
int64 getMilliseconds();
|
||||
void put(int64 milliseconds);
|
||||
|
||||
int64 getMilliseconds(); // milliseconds since epoch
|
||||
private:
|
||||
static int64 diffInt(TimeStamp const &left,TimeStamp const &right );
|
||||
int64 secondsPastEpoch;
|
||||
|
||||
+46
-68
@@ -87,14 +87,14 @@ ConstructDestructCallback * Timer::getConstructDestructCallback()
|
||||
|
||||
class TimerNodePvt;
|
||||
|
||||
typedef LinkedListNode<TimerNodePvt> ListNode;
|
||||
typedef LinkedList<TimerNodePvt> List;
|
||||
typedef LinkedListNode<TimerNodePvt> TimerListNode;
|
||||
typedef LinkedList<TimerNodePvt> TimerList;
|
||||
|
||||
class TimerNodePvt {
|
||||
public:
|
||||
TimerNode *timerNode;
|
||||
TimerCallback *callback;
|
||||
ListNode *listNode;
|
||||
TimerListNode *timerListNode;
|
||||
TimeStamp timeToRun;
|
||||
TimerPvt *timerPvt;
|
||||
double period;
|
||||
@@ -104,65 +104,63 @@ public:
|
||||
|
||||
TimerNodePvt::TimerNodePvt(TimerNode *timerNode,TimerCallback *callback)
|
||||
: timerNode(timerNode),callback(callback),
|
||||
listNode(new ListNode(this)),timeToRun(TimeStamp()),
|
||||
timerListNode(new TimerListNode(this)),timeToRun(TimeStamp()),
|
||||
timerPvt(0), period(0.0)
|
||||
{}
|
||||
|
||||
TimerNodePvt::~TimerNodePvt()
|
||||
{
|
||||
delete listNode;
|
||||
delete timerListNode;
|
||||
}
|
||||
|
||||
struct TimerPvt : public RunnableReady {
|
||||
struct TimerPvt : public Runnable{
|
||||
public:
|
||||
TimerPvt(String threadName,ThreadPriority priority);
|
||||
~TimerPvt();
|
||||
virtual void run(ThreadReady *threadReady);
|
||||
virtual void run();
|
||||
public: // only used by this source module
|
||||
List *list;
|
||||
TimerList *timerList;
|
||||
Mutex mutex;
|
||||
Event *waitForWork;
|
||||
Event *waitForDone;
|
||||
Thread *thread;
|
||||
volatile bool alive;
|
||||
Thread *thread;
|
||||
};
|
||||
|
||||
TimerPvt::TimerPvt(String threadName,ThreadPriority priority)
|
||||
: list(new List()),
|
||||
: timerList(new TimerList()),
|
||||
mutex(Mutex()),
|
||||
waitForWork(new Event(eventEmpty)),
|
||||
waitForDone(new Event(eventEmpty)),
|
||||
thread(new Thread(threadName,priority,this)),
|
||||
alive(true)
|
||||
{
|
||||
thread->start();
|
||||
}
|
||||
waitForWork(new Event(false)),
|
||||
waitForDone(new Event(false)),
|
||||
alive(true),
|
||||
thread(new Thread(threadName,priority,this))
|
||||
{}
|
||||
|
||||
TimerPvt::~TimerPvt()
|
||||
{
|
||||
delete thread;
|
||||
delete waitForDone;
|
||||
delete waitForWork;
|
||||
delete list;
|
||||
delete timerList;
|
||||
}
|
||||
|
||||
static void addElement(TimerPvt *timer,TimerNodePvt *node)
|
||||
{
|
||||
List *list = timer->list;
|
||||
ListNode *nextNode = list->getHead();
|
||||
TimerList *timerList = timer->timerList;
|
||||
TimerListNode *nextNode = timerList->getHead();
|
||||
if(nextNode==0) {
|
||||
list->addTail(node->listNode);
|
||||
timerList->addTail(node->timerListNode);
|
||||
return;
|
||||
}
|
||||
while(true) {
|
||||
TimerNodePvt *listNode = nextNode->getObject();
|
||||
if((node->timeToRun)<(listNode->timeToRun)) {
|
||||
list->insertBefore(listNode->listNode,node->listNode);
|
||||
TimerNodePvt *timerListNode = nextNode->getObject();
|
||||
if((node->timeToRun)<(timerListNode->timeToRun)) {
|
||||
timerList->insertBefore(timerListNode->timerListNode,node->timerListNode);
|
||||
return;
|
||||
}
|
||||
nextNode = list->getNext(listNode->listNode);
|
||||
nextNode = timerList->getNext(timerListNode->timerListNode);
|
||||
if(nextNode==0) {
|
||||
list->addTail(node->listNode);
|
||||
timerList->addTail(node->timerListNode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -177,31 +175,22 @@ TimerNode::TimerNode(TimerCallback *callback)
|
||||
totalNodeConstruct++;
|
||||
}
|
||||
|
||||
TimerNode *TimerNode::create(TimerCallback *callback)
|
||||
{
|
||||
return new TimerNode(callback);
|
||||
}
|
||||
|
||||
TimerNode::~TimerNode()
|
||||
{
|
||||
cancel();
|
||||
delete pImpl;
|
||||
Lock xx(globalMutex);
|
||||
totalNodeDestruct++;
|
||||
}
|
||||
|
||||
void TimerNode::destroy()
|
||||
{
|
||||
cancel();
|
||||
delete this;
|
||||
}
|
||||
|
||||
void TimerNode::cancel()
|
||||
{
|
||||
TimerPvt *timerPvt = pImpl->timerPvt;
|
||||
if(timerPvt==0) return;
|
||||
Lock xx(&timerPvt->mutex);
|
||||
if(pImpl->timerPvt==0) return;
|
||||
pImpl->timerPvt->list->remove(pImpl);
|
||||
pImpl->timerPvt->timerList->remove(pImpl);
|
||||
pImpl->timerPvt = 0;
|
||||
}
|
||||
|
||||
@@ -210,13 +199,12 @@ bool TimerNode::isScheduled()
|
||||
TimerPvt *pvt = pImpl->timerPvt;
|
||||
if(pvt==0) return false;
|
||||
Lock xx(&pvt->mutex);
|
||||
return pImpl->listNode->isOnList();
|
||||
return pImpl->timerListNode->isOnList();
|
||||
}
|
||||
|
||||
|
||||
void TimerPvt::run(ThreadReady *threadReady)
|
||||
void TimerPvt::run()
|
||||
{
|
||||
threadReady->ready();
|
||||
TimeStamp currentTime;
|
||||
while(alive) {
|
||||
currentTime.getCurrent();
|
||||
@@ -225,25 +213,25 @@ void TimerPvt::run(ThreadReady *threadReady)
|
||||
TimerNodePvt *nodeToCall = 0;
|
||||
{
|
||||
Lock xx(&mutex);
|
||||
ListNode *listNode = list->getHead();
|
||||
if(listNode!=0) {
|
||||
TimerNodePvt *timerNodePvt = listNode->getObject();
|
||||
TimerListNode *timerListNode = timerList->getHead();
|
||||
if(timerListNode!=0) {
|
||||
TimerNodePvt *timerNodePvt = timerListNode->getObject();
|
||||
timeToRun = &timerNodePvt->timeToRun;
|
||||
double diff = TimeStamp::diff(
|
||||
*timeToRun,currentTime);
|
||||
if(diff<=0.0) {
|
||||
nodeToCall = timerNodePvt;
|
||||
list->removeHead();
|
||||
timerList->removeHead();
|
||||
period = timerNodePvt->period;
|
||||
if(period>0) {
|
||||
if(period>0.0) {
|
||||
timerNodePvt->timeToRun += period;
|
||||
addElement(this,timerNodePvt);
|
||||
} else {
|
||||
timerNodePvt->timerPvt = 0;
|
||||
}
|
||||
listNode = list->getHead();
|
||||
if(listNode!=0) {
|
||||
timerNodePvt = listNode->getObject();
|
||||
timerListNode = timerList->getHead();
|
||||
if(timerListNode!=0) {
|
||||
timerNodePvt = timerListNode->getObject();
|
||||
timeToRun = &timerNodePvt->timeToRun;
|
||||
} else {
|
||||
timeToRun = 0;
|
||||
@@ -273,31 +261,21 @@ Timer::Timer(String threadName, ThreadPriority priority)
|
||||
totalTimerConstruct++;
|
||||
}
|
||||
|
||||
Timer * Timer::create(String threadName, ThreadPriority priority)
|
||||
{
|
||||
return new Timer(threadName,priority);
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
delete pImpl;
|
||||
Lock xx(globalMutex);
|
||||
totalTimerDestruct++;
|
||||
}
|
||||
|
||||
void Timer::destroy()
|
||||
{
|
||||
{
|
||||
Lock xx(&pImpl->mutex);
|
||||
pImpl->alive = false;
|
||||
pImpl->waitForWork->signal();
|
||||
pImpl->waitForDone->wait();
|
||||
}
|
||||
List *list = pImpl->list;
|
||||
ListNode *node = 0;
|
||||
while((node = list->removeHead())!=0) {
|
||||
pImpl->waitForWork->signal();
|
||||
pImpl->waitForDone->wait();
|
||||
TimerList *timerList = pImpl->timerList;
|
||||
TimerListNode *node = 0;
|
||||
while((node = timerList->removeHead())!=0) {
|
||||
node->getObject()->callback->timerStopped();
|
||||
}
|
||||
delete this;
|
||||
delete pImpl;
|
||||
Lock xx(globalMutex);
|
||||
totalTimerDestruct++;
|
||||
}
|
||||
|
||||
void Timer::scheduleAfterDelay(TimerNode *timerNode,double delay)
|
||||
@@ -307,7 +285,7 @@ void Timer::scheduleAfterDelay(TimerNode *timerNode,double delay)
|
||||
void Timer::schedulePeriodic(TimerNode *timerNode,double delay,double period)
|
||||
{
|
||||
TimerNodePvt *timerNodePvt = timerNode->pImpl;
|
||||
if(timerNodePvt->listNode->isOnList()) {
|
||||
if(timerNodePvt->timerListNode->isOnList()) {
|
||||
throw std::logic_error(String("already queued"));
|
||||
}
|
||||
if(!pImpl->alive) {
|
||||
@@ -323,7 +301,7 @@ void Timer::schedulePeriodic(TimerNode *timerNode,double delay,double period)
|
||||
Lock xx(&pImpl->mutex);
|
||||
timerNodePvt->timerPvt = pImpl;
|
||||
addElement(pImpl,timerNodePvt);
|
||||
TimerNodePvt *first = pImpl->list->getHead()->getObject();
|
||||
TimerNodePvt *first = pImpl->timerList->getHead()->getObject();
|
||||
if(first==timerNodePvt) isFirst = true;
|
||||
}
|
||||
if(isFirst) pImpl->waitForWork->signal();
|
||||
|
||||
@@ -27,28 +27,24 @@ public:
|
||||
|
||||
class TimerNode : private NoDefaultMethods {
|
||||
public:
|
||||
TimerNode(TimerCallback *timerCallback);
|
||||
~TimerNode();
|
||||
static ConstructDestructCallback *getConstructDestructCallback();
|
||||
static TimerNode *create(TimerCallback *timerCallback);
|
||||
void destroy();
|
||||
void cancel();
|
||||
bool isScheduled();
|
||||
private:
|
||||
TimerNode(TimerCallback *timerCallback);
|
||||
~TimerNode();
|
||||
class TimerNodePvt *pImpl;
|
||||
friend class Timer;
|
||||
};
|
||||
|
||||
class Timer : private NoDefaultMethods {
|
||||
public:
|
||||
Timer(String threadName, ThreadPriority priority);
|
||||
~Timer();
|
||||
static ConstructDestructCallback *getConstructDestructCallback();
|
||||
static Timer * create(String threadName, ThreadPriority priority);
|
||||
void destroy();
|
||||
void scheduleAfterDelay(TimerNode *timerNode,double delay);
|
||||
void schedulePeriodic(TimerNode *timerNode,double delay,double period);
|
||||
private:
|
||||
Timer(String threadName, ThreadPriority priority);
|
||||
~Timer();
|
||||
class TimerPvt *pImpl;
|
||||
friend class TimerNode;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user