diff options
Diffstat (limited to 'vdr-vdrmanager')
-rw-r--r-- | vdr-vdrmanager/select.cpp | 317 |
1 files changed, 147 insertions, 170 deletions
diff --git a/vdr-vdrmanager/select.cpp b/vdr-vdrmanager/select.cpp index 1a463b1..06d9103 100644 --- a/vdr-vdrmanager/select.cpp +++ b/vdr-vdrmanager/select.cpp @@ -10,196 +10,173 @@ #include "handler.h" #include "helpers.h" -struct node -{ - cVdrmanagerClientSocket * socket; - node * next; +struct node { + cVdrmanagerClientSocket * socket; + node * next; }; -cSelect::cSelect() -{ - serversocket = NULL; - clientsockets = NULL; - clientsocketcount = 0; - handler = new cHandler; - pollfds = NULL; - stopped = false; - nexttimer = 0; - shutdown = 0; +cSelect::cSelect() { + serversocket = NULL; + clientsockets = NULL; + clientsocketcount = 0; + handler = new cHandler; + pollfds = NULL; + stopped = false; + nexttimer = 0; + shutdown = 0; } -cSelect::~cSelect() -{ - if (serversocket) - delete serversocket; +cSelect::~cSelect() { + if (serversocket) + delete serversocket; - while(clientsockets) - { - node * next = clientsockets->next; - delete clientsockets->socket; - delete clientsockets; - clientsockets = next; - } + while (clientsockets) { + node * next = clientsockets->next; + delete clientsockets->socket; + delete clientsockets; + clientsockets = next; + } - if (handler) - delete handler; + if (handler) + delete handler; - if (pollfds) - delete pollfds; + if (pollfds) + delete pollfds; } -void cSelect::SetServerSocket(cVdrmanagerServerSocket * sock) -{ - serversocket = sock; +void cSelect::SetServerSocket(cVdrmanagerServerSocket * sock) { + serversocket = sock; } -void cSelect::AddClientSocket(cVdrmanagerClientSocket * sock) -{ - // remember socket - node * newnode = new node; - newnode->next = clientsockets; - newnode->socket = sock; - clientsockets = newnode; - clientsocketcount++; +void cSelect::AddClientSocket(cVdrmanagerClientSocket * sock) { + // remember socket + node * newnode = new node; + newnode->next = clientsockets; + newnode->socket = sock; + clientsockets = newnode; + clientsocketcount++; } -void cSelect::RemoveClientSocket(cVdrmanagerClientSocket * sock) -{ - node * curnode = clientsockets; - node * lastnode = NULL; - while(curnode) - { - if (curnode->socket == sock) - { - // unlink node - if (lastnode) - lastnode->next = curnode->next; - else - clientsockets = curnode->next; - - // free socket and node - delete curnode->socket; - delete curnode; - - clientsocketcount--; - break; - } - lastnode = curnode; - curnode = curnode->next; - } - - if (clientsockets) - { - curnode = clientsockets; - while (curnode) - { - curnode = curnode->next; - } - } +void cSelect::RemoveClientSocket(cVdrmanagerClientSocket * sock) { + node * curnode = clientsockets; + node * lastnode = NULL; + while (curnode) { + if (curnode->socket == sock) { + // unlink node + if (lastnode) + lastnode->next = curnode->next; + else + clientsockets = curnode->next; + + // free socket and node + delete curnode->socket; + delete curnode; + + clientsocketcount--; + break; + } + lastnode = curnode; + curnode = curnode->next; + } + + if (clientsockets) { + curnode = clientsockets; + while (curnode) { + curnode = curnode->next; + } + } } -cVdrmanagerClientSocket * cSelect::GetClientSocket(int sock) -{ - node * curnode = clientsockets; - while (curnode) - { - if (curnode->socket->GetSocket() == sock) - return curnode->socket; - curnode = curnode->next; - } - - return NULL; +cVdrmanagerClientSocket * cSelect::GetClientSocket(int sock) { + node * curnode = clientsockets; + while (curnode) { + if (curnode->socket->GetSocket() == sock) + return curnode->socket; + curnode = curnode->next; + } + + return NULL; } -bool cSelect::Action() -{ - for(;!stopped;) - { - if (!Poll()) - return false; - } +bool cSelect::Action() { + for (; !stopped;) { + if (!Poll()) + return false; + } - return true; + return true; } -void cSelect::CreatePollfds() -{ - // construct pollfd array - // we need one pollfd for the eventpipe, - // the serversocket and each clientsocket - pollfds = new struct pollfd[clientsocketcount+1]; - pollfds[0].fd = serversocket->GetSocket(); - pollfds[0].events = POLLIN; - - node * curnode = clientsockets; - int i = 1; - while (curnode) - { - pollfds[i].fd = curnode->socket->GetSocket(); - pollfds[i].events = POLLIN; - if (curnode->socket->WritePending()) - pollfds[i].events |= POLLOUT; - pollfds[i++].revents = 0; - curnode = curnode->next; - } +void cSelect::CreatePollfds() { + // construct pollfd array + // we need one pollfd for the eventpipe, + // the serversocket and each clientsocket + pollfds = new struct pollfd[clientsocketcount + 1]; + pollfds[0].fd = serversocket->GetSocket(); + pollfds[0].events = POLLIN; + + node * curnode = clientsockets; + int i = 1; + while (curnode) { + pollfds[i].fd = curnode->socket->GetSocket(); + pollfds[i].events = POLLIN; + if (curnode->socket->WritePending()) + pollfds[i].events |= POLLOUT; + pollfds[i++].revents = 0; + curnode = curnode->next; + } } -bool cSelect::Poll() -{ - // poll for events - CreatePollfds(); - int rc = poll(pollfds, clientsocketcount+1, -1); - if (rc < 0) - { - LOG_ERROR; - delete pollfds; - return false; - } - - // timeout? - if (rc == 0) - return true; - - // client requests or outstanding writes - for(int i = 1; i < clientsocketcount+1; i++) - { - cVdrmanagerClientSocket * sock = GetClientSocket(pollfds[i].fd); - if (sock) - { - if (pollfds[i].revents & (POLLIN|POLLHUP)) - { - // client request - handler->HandleClientRequest(sock); - - // disconnect? - if (sock->Disconnected()) - { - RemoveClientSocket(sock); - } - } - else if (pollfds[i].revents & POLLOUT) - { - // possibly outstanding writes - sock->Flush(); - } - } - } - - // new client? - if (pollfds[0].revents & POLLIN) - { - // get client socket - cVdrmanagerClientSocket * sock = serversocket->Accept(); - if (sock) - { - // Add client socket - AddClientSocket(sock); - // Send current data - handler->HandleNewClient(sock); - } - } - - delete pollfds; - - return true; +bool cSelect::Poll() { + // poll for events + CreatePollfds(); + int rc = 0; + while ((rc = poll(pollfds, clientsocketcount + 1, -1)) < 0) { + if (errno != EINTR) + break; + } + if (rc < 0) { + LOG_ERROR; + delete pollfds; + return false; + } + + // timeout? + if (rc == 0) + return true; + + // client requests or outstanding writes + for (int i = 1; i < clientsocketcount + 1; i++) { + cVdrmanagerClientSocket * sock = GetClientSocket(pollfds[i].fd); + if (sock) { + if (pollfds[i].revents & (POLLIN | POLLHUP)) { + // client request + handler->HandleClientRequest(sock); + + // disconnect? + if (sock->Disconnected()) { + RemoveClientSocket(sock); + } + } else if (pollfds[i].revents & POLLOUT) { + // possibly outstanding writes + sock->Flush(); + } + } + } + + // new client? + if (pollfds[0].revents & POLLIN) { + // get client socket + cVdrmanagerClientSocket * sock = serversocket->Accept(); + if (sock) { + // Add client socket + AddClientSocket(sock); + // Send current data + handler->HandleNewClient(sock); + } + } + + delete pollfds; + + return true; } |