Skip to content

Commit

Permalink
Add ClientPool
Browse files Browse the repository at this point in the history
Clients are created and kept in the pool at first.
ClientList gets a free client from the pool.

Signed-off-by: tomoaki <[email protected]>
  • Loading branch information
ty4tw committed May 25, 2021
1 parent 740faeb commit 982e6d4
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 25 deletions.
5 changes: 3 additions & 2 deletions MQTTSNGateway/src/MQTTSNGWClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ char* currentDateTime(void);
Class Client
=====================================*/
static const char* theClientStatus[] =
{ "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep", "Awake",
{ "InPool", "Disconnected", "TryConnecting", "Connecting", "Active", "Asleep",
"Awake",
"Lost" };

Client::Client(bool secure)
{
_packetId = 0;
_snMsgId = 0;
_status = Cstat_Disconnected;
_status = Cstat_Free;
_keepAliveMsec = 0;
_topics = new Topics();
_clientId = nullptr;
Expand Down
4 changes: 3 additions & 1 deletion MQTTSNGateway/src/MQTTSNGWClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,8 @@ class WaitREGACKPacketList
=====================================*/
typedef enum
{
Cstat_Disconnected = 0,
Cstat_Free = 0,
Cstat_Disconnected,
Cstat_TryConnecting,
Cstat_Connecting,
Cstat_Active,
Expand All @@ -176,6 +177,7 @@ class Forwarder;
class Client
{
friend class ClientList;
friend class ClientsPool;
public:
Client(bool secure = false);
Client(uint8_t maxInflightMessages, bool secure);
Expand Down
117 changes: 97 additions & 20 deletions MQTTSNGateway/src/MQTTSNGWClientList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,20 @@
#include <string>

using namespace MQTTSNGW;
extern Gateway* theGateway;
char* currentDateTime(void);
/*=====================================
Class ClientList
=====================================*/
const char* common_topic = "*";

ClientList::ClientList()
ClientList::ClientList(Gateway* gw)
{
_clientCnt = 0;
_authorize = false;
_firstClient = nullptr;
_endClient = nullptr;
_clientsPool = new ClientsPool();
_gateway = gw;
}

ClientList::~ClientList()
Expand All @@ -46,12 +48,19 @@ ClientList::~ClientList()
delete cl;
cl = ncl;
};

if (_clientsPool)
{
delete _clientsPool;
}
_mutex.unlock();
}

void ClientList::initialize(bool aggregate)
{
if (theGateway->getGWParams()->clientAuthentication)
_clientsPool->allocate(_gateway->getGWParams()->maxClients);

if (_gateway->getGWParams()->clientAuthentication)
{
int type = TRANSPEARENT_TYPE;
if (aggregate)
Expand All @@ -62,28 +71,29 @@ void ClientList::initialize(bool aggregate)
_authorize = true;
}

if (theGateway->getGWParams()->predefinedTopic)
if (_gateway->getGWParams()->predefinedTopic)
{
setPredefinedTopics(aggregate);
}
}

void ClientList::setClientList(int type)
{
if (!createList(theGateway->getGWParams()->clientListName, type))
if (!createList(_gateway->getGWParams()->clientListName, type))
{
throw EXCEPTION(
"ClientList::setClientList No client list defined by config file.", 0);
"ClientList::setClientList Client list not found!", 0);
}
}

void ClientList::setPredefinedTopics(bool aggrecate)
{
if (!readPredefinedList(theGateway->getGWParams()->predefinedTopicFileName,
if (!readPredefinedList(_gateway->getGWParams()->predefinedTopicFileName,
aggrecate))
{
throw EXCEPTION(
"ClientList::setPredefinedTopics No predefindTopi list defined by config file.",0);
"ClientList::setPredefinedTopics PredefindTopic list not found!",
0);

}
}
Expand Down Expand Up @@ -158,7 +168,7 @@ bool ClientList::createList(const char* fileName, int type)
}
else if (forwarder && type == FORWARDER_TYPE)
{
theGateway->getAdapterManager()->getForwarderList()->addForwarder(
_gateway->getAdapterManager()->getForwarderList()->addForwarder(
&netAddr, &clientId);
}
else if (type == TRANSPEARENT_TYPE)
Expand Down Expand Up @@ -338,22 +348,23 @@ Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
Client* ClientList::createClient(SensorNetAddress* addr, MQTTSNString* clientId,
bool unstableLine, bool secure, int type)
{
Client* client = nullptr;

/* anonimous clients */
if (_clientCnt > MAX_CLIENTS)
Client* client = getClient(addr);
if (client)
{
return 0; // full of clients
return client;
}

client = getClient(addr);
if (client)
/* acquire a free client */
client = _clientsPool->getClient();

if (!client)
{
return client;
WRITELOG("%s%sMax number of Clients%s\n", currentDateTime(),
ERRMSG_HEADER, ERRMSG_FOOTER);
return nullptr;
}

/* creat a new client */
client = new Client(secure);
client->disconnected();
if (addr)
{
client->setClientAddress(addr);
Expand Down Expand Up @@ -411,7 +422,7 @@ Client* ClientList::createPredefinedTopic(MQTTSNString* clientId,

if (strcmp(clientId->cstring, common_topic) == 0)
{
theGateway->getTopics()->add((const char*) topicName.c_str(), topicId);
_gateway->getTopics()->add((const char*) topicName.c_str(), topicId);
return nullptr;
}
else
Expand Down Expand Up @@ -473,3 +484,69 @@ bool ClientList::isAuthorized()
return _authorize;
}

/******************************
* Class ClientsPool
******************************/

ClientsPool::ClientsPool()
{
_clientCnt = 0;
_firstClient = nullptr;
_endClient = nullptr;
}

ClientsPool::~ClientsPool()
{
Client* cl = _firstClient;
Client* ncl;

while (cl != nullptr)
{
ncl = cl->_nextClient;
delete cl;
cl = ncl;
};
}

void ClientsPool::allocate(int maxClients)
{
Client* cl = nullptr;

_firstClient = new Client();

for (int i = 0; i < maxClients; i++)
{
if ((cl = new Client()) == nullptr)
{
throw Exception(
"ClientsPool::Can't allocate max number of clients\n", 0);
}
cl->_nextClient = _firstClient;
_firstClient = cl;
_clientCnt++;
}

}

Client* ClientsPool::getClient(void)
{
while (_firstClient != nullptr)
{
Client* cl = _firstClient;
_firstClient = cl->_nextClient;
cl->_nextClient = nullptr;
_clientCnt--;
return cl;
}
return nullptr;
}

void ClientsPool::setClient(Client* client)
{
if (client)
{
client->_nextClient = _firstClient;
_firstClient = client;
_clientCnt++;
}
}
23 changes: 21 additions & 2 deletions MQTTSNGateway/src/MQTTSNGWClientList.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,31 @@ namespace MQTTSNGW

class Client;

/*=====================================
Class ClientsPool
=====================================*/
class ClientsPool
{
public:
ClientsPool();
~ClientsPool();
void allocate(int maxClients);
Client* getClient(void);
void setClient(Client* client);

private:
Client* _firstClient;
Client* _endClient;
int _clientCnt;
};

/*=====================================
Class ClientList
=====================================*/
class ClientList
{
public:
ClientList();
ClientList(Gateway* gw);
~ClientList();

void initialize(bool aggregate);
Expand All @@ -57,7 +75,8 @@ class ClientList

private:
bool readPredefinedList(const char* fileName, bool _aggregate);
Gateway* _gateway { nullptr };
ClientsPool* _clientsPool;
Gateway* _gateway;
Client* createPredefinedTopic(MQTTSNString* clientId, string topicName,
uint16_t toipcId, bool _aggregate);
Client* _firstClient;
Expand Down

0 comments on commit 982e6d4

Please sign in to comment.