Added Identity Info retrieval to rsIdentities.

This is now pretty much complete for Phase 1 of GXS.
Still todo:
	- PGPHash signatures.
	- Reputations.

 - Added two helper classes GxsTokenQueue: similar to TokenQueue, but for libretroshare
       & RsTickEvent: schedule one shot events, and basic stats.
 - Reorganised/simplified p3IdService using these two classes.
 - Added fns to load/reload a list of Own Identities.
 - Improved the Cache to store all GUI required Info.
 - Updater retroshare/rsidentity.h with new Identity interface.
 - added fns to update Cache from internal background tasks.
 - Modified RsMemCache to support replace operation.
 - Found nasty Bug that caused PGPHASHes not to match & Patched same bug in GXS.
 - added generic CacheArbitration.
 - Added AuthorIds to dummy Forum messages.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-gxs-b1@5848 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2012-11-19 22:00:05 +00:00
parent 6e349749d0
commit c6e6d444bf
13 changed files with 1096 additions and 491 deletions

View File

@ -0,0 +1,95 @@
/*
* libretroshare/src/gxs gxstokenqueue.cc
*
* Gxs Support for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "gxs/gxstokenqueue.h"
bool GxsTokenQueue::queueRequest(uint32_t token, uint32_t req_type)
{
RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/
mQueue.push_back(GxsTokenQueueItem(token, req_type));
return true;
}
void GxsTokenQueue::checkRequests()
{
{
RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/
if (mQueue.empty())
{
return;
}
}
// Must check all, and move to a different list - for reentrant / good mutex behaviour.
std::list<GxsTokenQueueItem> toload;
std::list<GxsTokenQueueItem>::iterator it;
bool stuffToLoad = false;
{
RsStackMutex stack(mQueueMtx); /********** STACK LOCKED MTX ******/
for(it = mQueue.begin(); it != mQueue.end();)
{
uint32_t token = it->mToken;
uint32_t status = mGenExchange->getTokenService()->requestStatus(token);
if (status == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE)
{
toload.push_back(*it);
it = mQueue.erase(it);
stuffToLoad = true;
}
else if (status == RsTokenService::GXS_REQUEST_V2_STATUS_FAILED)
{
// maybe we should do alternative callback?
std::cerr << "GxsTokenQueue::checkRequests() ERROR Request Failed: " << token;
std::cerr << std::endl;
it = mQueue.erase(it);
}
else
{
it++;
}
}
}
if (stuffToLoad)
{
for(it = toload.begin(); it != toload.end(); it++)
{
handleResponse(it->mToken, it->mReqType);
}
}
}
// This must be overloaded to complete the functionality.
void GxsTokenQueue::handleResponse(uint32_t token, uint32_t req_type)
{
std::cerr << "GxsTokenQueue::handleResponse(" << token << "," << req_type << ") ERROR: NOT HANDLED";
std::cerr << std::endl;
}

View File

@ -0,0 +1,71 @@
#ifndef R_GXS_TOKEN_QUEUE_H
#define R_GXS_TOKEN_QUEUE_H
/*
* libretroshare/src/gxs gxstokenqueue.h
*
* Gxs Support for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "gxs/rsgenexchange.h"
#include "util/rsthreads.h"
/*
*
* A little helper class, to manage callbacks from requests
*
*/
class GxsTokenQueueItem
{
public:
GxsTokenQueueItem(const uint32_t token, const uint32_t req_type)
:mToken(token),mReqType(req_type) { return; }
GxsTokenQueueItem(): mToken(0), mReqType(0) { return; }
uint32_t mToken;
uint32_t mReqType;
};
class GxsTokenQueue
{
public:
GxsTokenQueue(RsGenExchange *gxs)
:mGenExchange(gxs), mQueueMtx("GxsTokenQueueMtx") { return; }
bool queueRequest(uint32_t token, uint32_t req_type);
void checkRequests(); // must be called by
// This must be overloaded to complete the functionality.
virtual void handleResponse(uint32_t token, uint32_t req_type);
private:
RsGenExchange *mGenExchange;
RsMutex mQueueMtx;
std::list<GxsTokenQueueItem> mQueue;
};
#endif //R_GXS_TOKEN_QUEUE_H

View File

@ -396,7 +396,7 @@ bool RsGenExchange::createMsgSignatures(RsTlvKeySignatureSet& signSet, RsTlvBina
for(; mit != mit_end; mit++)
{
pub_key_found = mit->second.keyFlags & (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL);
pub_key_found = mit->second.keyFlags == (RSTLV_KEY_DISTRIB_PRIVATE | RSTLV_KEY_TYPE_FULL);
if(pub_key_found)
break;
}
@ -1342,7 +1342,7 @@ void RsGenExchange::publishGrps()
{
RsTlvSecurityKey& key = mit_keys->second;
if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
{
privAdminKey = key;
privKeyFound = true;
@ -1493,7 +1493,7 @@ void RsGenExchange::createDummyGroup(RsGxsGrpItem *grpItem)
{
RsTlvSecurityKey& key = mit_keys->second;
if(key.keyFlags & (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
if(key.keyFlags == (RSTLV_KEY_DISTRIB_ADMIN | RSTLV_KEY_TYPE_FULL))
{
privAdminKey = key;
privKeyFound = true;

View File

@ -430,7 +430,8 @@ HEADERS += retroshare/rsgame.h \
util/rsrandom.h \
util/radix64.h \
util/pugiconfig.h \
util/rsmemcache.h
util/rsmemcache.h \
util/rstickevent.h
SOURCES += dbase/cachestrapper.cc \
dbase/fimonitor.cc \
@ -564,7 +565,8 @@ HEADERS += retroshare/rsgame.h \
util/rsthreads.cc \
util/rsversion.cc \
util/rswin.cc \
util/rsrandom.cc
util/rsrandom.cc \
util/rstickevent.cc
upnp_miniupnpc {
HEADERS += upnp/upnputil.h upnp/upnphandler_miniupnp.h
@ -614,6 +616,7 @@ HEADERS += retroshare/rsgame.h \
gxs/gxscoreserver.h \
gxs/gxssecurity.h \
gxs/rsgxsifaceimpl.h \
gxs/gxstokenqueue.h \
services/p3posted.h \
retroshare/rsposted.h \
serialiser/rsposteditems.h
@ -633,6 +636,7 @@ HEADERS += retroshare/rsgame.h \
gxs/gxscoreserver.cc \
gxs/gxssecurity.cc \
gxs/rsgxsifaceimpl.cc \
gxs/gxstokenqueue.cc \
services/p3posted.cc \
serialiser/rsposteditems.cc

View File

@ -89,8 +89,6 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group) = 0;
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg) = 0;
virtual bool generateDummyData() = 0;
};

View File

@ -160,13 +160,24 @@ typedef std::string RsGxsId; // TMP. =>
class RsIdentityDetails
{
public:
RsIdentityDetails()
:mIsOwnId(false), mPgpLinked(false), mPgpKnown(false),
mOpinion(0), mReputation(0) { return; }
RsGxsId id;
RsGxsId mId;
// identity details.
std::string mNickname;
bool mIsOwnId;
// PGP Stuff.
bool mPgpLinked;
bool mPgpKnown;
std::string mPgpId;
// reputation details.
double mOpinion;
double mReputation;
};
@ -261,7 +272,7 @@ public:
// We cache all identities, and provide alternative (instantaneous)
// functions to extract info, rather than the standard Token system.
virtual bool getNickname(const RsGxsId &id, std::string &nickname) = 0;
//virtual bool getNickname(const RsGxsId &id, std::string &nickname) = 0;
virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details) = 0;
virtual bool getOwnIds(std::list<RsGxsId> &ownIds) = 0;

View File

@ -26,6 +26,8 @@
#include "services/p3gxsforums.h"
#include "serialiser/rsgxsforumitems.h"
#include <retroshare/rsidentity.h>
#include "gxs/rsgxsflags.h"
#include <stdio.h>
@ -41,6 +43,8 @@
RsGxsForums *rsGxsForums = NULL;
#define FORUM_TESTEVENT_DUMMYDATA 0x0001
#define DUMMYDATA_PERIOD 60 // long enough for some RsIdentities to be generated.
/********************************************************************************/
/******************* Startup / Tick ******************************************/
@ -51,6 +55,7 @@ p3GxsForums::p3GxsForums(RsGeneralDataService *gds, RsNetworkExchangeService *ne
{
// For Dummy Msgs.
mGenActive = false;
RsTickEvent::schedule_in(FORUM_TESTEVENT_DUMMYDATA, DUMMYDATA_PERIOD);
}
void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
@ -61,6 +66,7 @@ void p3GxsForums::notifyChanges(std::vector<RsGxsNotify *> &changes)
void p3GxsForums::service_tick()
{
dummy_tick();
RsTickEvent::tick_events();
return;
}
@ -400,6 +406,28 @@ bool p3GxsForums::generateMessage(uint32_t &token, const RsGxsGroupId &grpId, co
msg.mMeta.mThreadId = threadId;
msg.mMeta.mParentId = parentId;
/* chose a random Id to sign with */
std::list<RsGxsId> ownIds;
std::list<RsGxsId>::iterator it;
rsIdentity->getOwnIds(ownIds);
uint32_t idx = (uint32_t) (ownIds.size() * RSRandom::random_f32());
int i = 0;
for(it = ownIds.begin(); (it != ownIds.end()) && (i < idx); it++, i++);
if (it != ownIds.end())
{
std::cerr << "p3GxsForums::generateMessage() Author: " << *it;
std::cerr << std::endl;
msg.mMeta.mAuthorId = *it;
}
else
{
std::cerr << "p3GxsForums::generateMessage() No Author!";
std::cerr << std::endl;
}
createMsg(token, msg);
return true;
@ -417,3 +445,25 @@ bool p3GxsForums::generateGroup(uint32_t &token, std::string groupName)
return true;
}
// Overloaded from RsTickEvent for Event callbacks.
void p3GxsForums::handle_event(uint32_t event_type)
{
std::cerr << "p3GxsForums::handle_event(" << event_type << ")";
std::cerr << std::endl;
// stuff.
switch(event_type)
{
case FORUM_TESTEVENT_DUMMYDATA:
generateDummyData();
break;
default:
/* error */
std::cerr << "p3GxsForums::handle_event() Unknown Event Type: " << event_type;
std::cerr << std::endl;
break;
}
}

View File

@ -30,6 +30,8 @@
#include "retroshare/rsgxsforums.h"
#include "gxs/rsgenexchange.h"
#include "util/rstickevent.h"
#include <map>
#include <string>
@ -37,7 +39,8 @@
*
*/
class p3GxsForums: public RsGenExchange, public RsGxsForums
class p3GxsForums: public RsGenExchange, public RsGxsForums,
public RsTickEvent /* only needed for testing - remove after */
{
public:
@ -66,9 +69,14 @@ virtual void setMessageReadStatus(uint32_t& token, const RsGxsGrpMsgIdPair& msgI
virtual bool createGroup(uint32_t &token, RsGxsForumGroup &group);
virtual bool createMsg(uint32_t &token, RsGxsForumMsg &msg);
virtual bool generateDummyData();
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type);
private:
virtual bool generateDummyData();
std::string genRandomId();
void dummy_tick();

File diff suppressed because it is too large Load Diff

View File

@ -31,10 +31,13 @@
#include "gxs/rsgenexchange.h" // GXS service.
#include "gxs/rsgixs.h" // Internal Interfaces.
#include "gxs/gxstokenqueue.h"
#include <map>
#include <string>
#include "util/rsmemcache.h"
#include "util/rstickevent.h"
#include "pqi/authgpg.h"
@ -132,31 +135,33 @@ class RsGxsIdCache
RsGxsIdCache();
RsGxsIdCache(const RsGxsIdGroupItem *item, const RsTlvSecurityKey &in_pkey);
RsGxsId id;
std::string name;
RsTlvSecurityKey pubkey;
double reputation;
time_t lastUsedTs;
void updateServiceString(std::string serviceString);
RsIdentityDetails details;
RsTlvSecurityKey pubkey;
};
#if 0
class LruData
{
public:
RsGxsId key;
};
#endif
// Not sure exactly what should be inherited here?
// Chris - please correct as necessary.
class p3IdService: public RsGxsIdExchange, public RsIdentity
class p3IdService: public RsGxsIdExchange, public RsIdentity,
public GxsTokenQueue, public RsTickEvent
{
public:
p3IdService(RsGeneralDataService* gds, RsNetworkExchangeService* nes);
virtual void service_tick(); // needed for background processing.
@ -174,12 +179,20 @@ virtual bool createMsg(uint32_t& token, RsGxsIdOpinion &opinion);
/**************** RsIdentity External Interface.
* Notes:
*
* All the data is cached together for the moment - We should probably
* seperate and sort this out.
*
* Also need to handle Cache updates / invalidation from internal changes.
*
*/
virtual bool getNickname(const RsGxsId &id, std::string &nickname);
//virtual bool getNickname(const RsGxsId &id, std::string &nickname);
virtual bool getIdDetails(const RsGxsId &id, RsIdentityDetails &details);
virtual bool getOwnIds(std::list<RsGxsId> &ownIds);
//
virtual bool submitOpinion(uint32_t& token, RsIdOpinion &opinion);
virtual bool createIdentity(uint32_t& token, RsIdentityParameters &params);
@ -208,6 +221,13 @@ virtual int getPrivateKey(const RsGxsId &id, RsTlvSecurityKey &key);
virtual bool getReputation(const RsGxsId &id, const GixsReputation &rep);
// Overloaded from GxsTokenQueue for Request callbacks.
virtual void handleResponse(uint32_t token, uint32_t req_type);
// Overloaded from RsTickEvent.
virtual void handle_event(uint32_t event_type);
protected:
/** Notifications **/
@ -226,20 +246,27 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key
bool cache_request_load(const RsGxsId &id);
bool cache_start_load();
bool cache_check_loading();
bool cache_load_for_token(uint32_t token);
bool cache_store(const RsGxsIdGroupItem *item);
bool cache_update_if_cached(const RsGxsId &id, std::string serviceString);
// Mutex protected.
time_t mCacheLoad_LastCycle;
int mCacheLoad_Status;
std::list<RsGxsId> mCacheLoad_ToCache;
std::list<uint32_t> mCacheLoad_Tokens;
// Switching to RsMemCache for Key Caching.
RsMemCache<RsGxsId, RsGxsIdCache> mPublicKeyCache;
RsMemCache<RsGxsId, RsGxsIdCache> mPrivateKeyCache;
/************************************************************************
* Refreshing own Ids.
*
*/
bool cache_request_ownids();
bool cache_load_ownids(uint32_t token);
std::list<RsGxsId> mOwnIds;
/************************************************************************
* Test fns for Caching.
@ -247,20 +274,14 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key
*/
bool cachetest_tick();
bool cachetest_getlist();
bool cachetest_request();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
time_t mCacheTest_LastTs;
bool mCacheTest_Active;
uint32_t mCacheTest_Token;
bool cachetest_handlerequest(uint32_t token);
/************************************************************************
* for processing background tasks that use the serviceString.
* - must be mutually exclusive to avoid clashes.
*/
int scheduling_tick();
bool CacheArbitration(uint32_t mode);
void CacheArbitrationDone(uint32_t mode);
bool mBgSchedule_Active;
uint32_t mBgSchedule_Mode;
@ -270,19 +291,13 @@ virtual void service_CreateGroup(RsGxsGrpItem* grpItem, RsTlvSecurityKeySet& key
*
*/
bool pgphash_start();
bool pgphash_continue();
bool pgphash_getlist();
bool pgphash_request();
bool pgphash_handlerequest(uint32_t token);
bool pgphash_process();
bool checkId(const RsGxsIdGroup &grp, PGPIdType &pgp_id);
void getPgpIdList();
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
time_t mHashPgp_LastTs;
bool mHashPgp_SearchActive;
uint32_t mHashPgp_Token;
/* MUTEX PROTECTED DATA (mIdMtx - maybe should use a 2nd?) */
std::map<PGPIdType, PGPFingerprintType> mPgpFingerprintMap;
std::list<RsGxsIdGroup> mGroupsToProcess;

View File

@ -133,20 +133,22 @@ template<class Key, class Value> bool RsMemCache<Key, Value>::store(const Key &k
std::cerr << "RsMemCache::store()";
std::cerr << std::endl;
/* update lrumap entry */
time_t old_ts = 0;
time_t new_ts = time(NULL);
// For consistency
typename std::map<Key, cache_data>::const_iterator it;
it = mDataMap.find(key);
if (it != mDataMap.end())
{
// ERROR.
std::cerr << "RsMemCache::store() ERROR entry exists already";
std::cerr << "RsMemCache::store() WARNING overriding existing entry";
std::cerr << std::endl;
return false;
old_ts = it->second.ts;
}
/* add new lrumap entry */
time_t old_ts = 0;
time_t new_ts = time(NULL);
mDataMap[key] = cache_data(key, data, new_ts);
mDataCount++;

View File

@ -0,0 +1,185 @@
/*
* libretroshare/src/util: rstickevent.cc
*
* Identity interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "util/rstickevent.h"
#include <iostream>
#include <list>
//#define DEBUG_EVENTS 1
void RsTickEvent::tick_events()
{
#ifdef DEBUG_EVENTS
std::cerr << "RsTickEvent::tick_events() Event List:";
std::cerr << std::endl;
#endif
time_t now = time(NULL);
{
RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/
#ifdef DEBUG_EVENTS
if (!mEvents.empty())
{
std::multimap<time_t, uint32_t>::iterator it;
for(it = mEvents.begin(); it != mEvents.end(); it++)
{
std::cerr << "\tEvent type: ";
std::cerr << it->second << " in " << it->first - now << " secs";
std::cerr << std::endl;
}
}
#endif
if (mEvents.empty())
{
return;
}
/* all events in the future */
if (mEvents.begin()->first > now)
{
return;
}
}
std::list<uint32_t> toProcess;
std::list<uint32_t>::iterator it;
{
RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/
while((!mEvents.empty()) && (mEvents.begin()->first <= now))
{
std::multimap<time_t, uint32_t>::iterator it = mEvents.begin();
uint32_t event_type = it->second;
toProcess.push_back(event_type);
mEvents.erase(it);
count_adjust_locked(event_type, -1);
}
}
for(it = toProcess.begin(); it != toProcess.end(); it++)
{
std::cerr << "RsTickEvent::tick_events() calling handle_event(";
std::cerr << *it << ")";
std::cerr << std::endl;
handle_event(*it);
}
}
void RsTickEvent::schedule_now(uint32_t event_type)
{
RsTickEvent::schedule_in(event_type, 0);
}
void RsTickEvent::schedule_event(uint32_t event_type, time_t when)
{
RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/
mEvents.insert(std::make_pair(when, event_type));
count_adjust_locked(event_type, 1);
}
void RsTickEvent::schedule_in(uint32_t event_type, uint32_t in_secs)
{
std::cerr << "RsTickEvent::schedule_in(" << event_type << ") in " << in_secs << " secs";
std::cerr << std::endl;
RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/
time_t event_time = time(NULL) + in_secs;
mEvents.insert(std::make_pair(event_time, event_type));
count_adjust_locked(event_type, 1);
}
void RsTickEvent::handle_event(uint32_t event_type)
{
std::cerr << "RsTickEvent::handle_event(" << event_type << ") ERROR Not Handled";
std::cerr << std::endl;
}
int32_t RsTickEvent::event_count(uint32_t event_type)
{
RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/
std::map<uint32_t, int32_t>::iterator it;
it = mEventCount.find(event_type);
if (it == mEventCount.end())
{
return 0;
}
return it->second;
}
bool RsTickEvent::prev_event_ago(uint32_t event_type, int32_t &age)
{
RsStackMutex stack(mEventMtx); /********** STACK LOCKED MTX ******/
std::map<uint32_t, time_t>::iterator it;
it = mPreviousEvent.find(event_type);
if (it == mPreviousEvent.end())
{
return false;
}
age = time(NULL) - it->second;
return true;
}
void RsTickEvent::count_adjust_locked(uint32_t event_type, int32_t change)
{
std::map<uint32_t, int32_t>::iterator it;
it = mEventCount.find(event_type);
if (it == mEventCount.end())
{
mEventCount[event_type] = 0;
it = mEventCount.find(event_type);
}
it->second += change;
if (it->second < 0)
{
std::cerr << "RsTickEvent::count_adjust() ERROR: COUNT < 0";
std::cerr << std::endl;
it->second = 0;
}
}
void RsTickEvent::note_event_locked(uint32_t event_type)
{
mPreviousEvent[event_type] = time(NULL);
}

View File

@ -0,0 +1,67 @@
/*
* libretroshare/src/util: rstickevent.h
*
* Identity interface for RetroShare.
*
* Copyright 2012-2012 by Robert Fernie.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2.1 as published by the Free Software Foundation.
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#ifndef RS_UTIL_TICK_EVENT
#define RS_UTIL_TICK_EVENT
/*
*
* A simple event queue... to avoid having to continually write separate one.
*/
#include <map>
#include <time.h>
#include "util/rsthreads.h"
class RsTickEvent
{
public:
RsTickEvent():mEventMtx("TickEventMtx") { return; }
void tick_events();
void schedule_now(uint32_t event_type);
void schedule_event(uint32_t event_type, time_t when);
void schedule_in(uint32_t event_type, uint32_t in_secs);
int32_t event_count(uint32_t event_type);
bool prev_event_ago(uint32_t event_type, int32_t &age);
// Overloaded to handle the events.
virtual void handle_event(uint32_t event_type);
private:
void count_adjust_locked(uint32_t event_type, int32_t change);
void note_event_locked(uint32_t event_type);
RsMutex mEventMtx;
std::map<uint32_t, int32_t> mEventCount;
std::map<uint32_t, time_t> mPreviousEvent;
std::multimap<time_t, uint32_t> mEvents;
};
#endif // RS_UTIL_TICK_EVENT