forked from sonic-net/sonic-swss
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The Select class implements ::select (2) API with multiple tables or file-descriptor. Usage: Select cs; cs.addSelectable(&netlink); cs.addSelectable(&consumerTable); while (true) { Selectable *object; int tempfd; if (s.select(&object, &tempfd) != Select::OBJECT) break; // Check if object is consumerTable or netlink } Signed-off-by: Elad Raz <[email protected]>
- Loading branch information
Showing
3 changed files
with
127 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
#include "common/selectable.h" | ||
#include "common/select.h" | ||
#include <stdio.h> | ||
#include <sys/time.h> | ||
#include <sys/types.h> | ||
|
||
using namespace std; | ||
|
||
namespace swss { | ||
|
||
void Select::addSelectable(Selectable *c) | ||
{ | ||
m_objects.push_back(c); | ||
} | ||
|
||
void Select::addFd(int fd) | ||
{ | ||
m_fds.push_back(fd); | ||
} | ||
|
||
int Select::select(Selectable **c, int *fd, unsigned int timeout) | ||
{ | ||
struct timeval t = {0, (suseconds_t)(timeout)*1000}; | ||
struct timeval *pTimeout = NULL; | ||
fd_set fs; | ||
int err; | ||
|
||
FD_ZERO(&fs); | ||
*c = NULL; | ||
*fd = 0; | ||
if (timeout != std::numeric_limits<unsigned int>::max()) | ||
pTimeout = &t; | ||
|
||
/* Checking caching from reader */ | ||
for (Selectable *i : m_objects) | ||
{ | ||
err = i->readCache(); | ||
if (err == Selectable::ERROR) | ||
return Select::ERROR; | ||
else if (err == Selectable::DATA) { | ||
*c = i; | ||
return Select::OBJECT; | ||
} | ||
/* else, timeout = no data */ | ||
|
||
i->addFd(&fs); | ||
} | ||
|
||
for (int fd : m_fds) | ||
{ | ||
FD_SET(fd, &fs); | ||
} | ||
|
||
err = ::select(FD_SETSIZE, &fs, NULL, NULL, pTimeout); | ||
if (err < 0) | ||
return Select::ERROR; | ||
if (err == 0) | ||
return Select::TIMEOUT; | ||
|
||
/* Check other consumer-table */ | ||
for (Selectable *i : m_objects) | ||
if (i->isMe(&fs)) | ||
{ | ||
i->readMe(); | ||
*c = i; | ||
return Select::OBJECT; | ||
} | ||
|
||
/* Check other FDs */ | ||
for (int f : m_fds) | ||
if (FD_ISSET(f, &fs)) | ||
{ | ||
*fd = f; | ||
return Select::FD; | ||
} | ||
|
||
/* Shouldn't reach here */ | ||
return Select::ERROR; | ||
} | ||
|
||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
#ifndef __CONSUMERSELECT__ | ||
#define __CONSUMERSELECT__ | ||
|
||
#include <string> | ||
#include <vector> | ||
#include <limits> | ||
#include <hiredis/hiredis.h> | ||
#include "common/selectable.h" | ||
|
||
namespace swss { | ||
|
||
class Select | ||
{ | ||
public: | ||
/* Add object for select */ | ||
void addSelectable(Selectable *c); | ||
|
||
/* Add file-descriptor for select */ | ||
void addFd(int fd); | ||
|
||
/* | ||
* Wait until data will arrived, returns the object on which select() | ||
* was signaled. | ||
*/ | ||
enum { | ||
OBJECT = 0, | ||
FD = 1, | ||
ERROR = 2, | ||
TIMEOUT = 3 | ||
}; | ||
int select(Selectable **c, int *fd, | ||
unsigned int timeout = std::numeric_limits<unsigned int>::max()); | ||
|
||
private: | ||
/* Create a new redisContext, SELECT DB and SUBSRIBE */ | ||
void subsribe(); | ||
|
||
std::vector<Selectable * > m_objects; | ||
std::vector<int> m_fds; | ||
}; | ||
|
||
} | ||
|
||
#endif |