Commit f3110e9007ab0636ee8872fba262b009c759c152

Authored by Wiebe Cazemier
1 parent 19f21bf2

Construct clients

CMakeLists.txt
... ... @@ -6,6 +6,6 @@ set(CMAKE_CXX_STANDARD 11)
6 6 set(CMAKE_CXX_STANDARD_REQUIRED ON)
7 7  
8 8  
9   -add_executable(FlashMQ main.cpp utils.cpp threaddata.cpp)
  9 +add_executable(FlashMQ main.cpp utils.cpp threaddata.cpp client.cpp)
10 10  
11 11 target_link_libraries(FlashMQ pthread)
... ...
client.cpp 0 → 100644
  1 +#include "client.h"
  2 +
  3 +Client::Client(int fd, ThreadData &threadData) :
  4 + fd(fd),
  5 + threadData(threadData)
  6 +{
  7 + int flags = fcntl(fd, F_GETFL);
  8 + fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  9 +}
  10 +
  11 +Client::~Client()
  12 +{
  13 + epoll_ctl(threadData.epollfd, EPOLL_CTL_DEL, fd, NULL); // NOTE: the last NULL can cause crash on old kernels
  14 + close(fd);
  15 +}
... ...
client.h 0 → 100644
  1 +#ifndef CLIENT_H
  2 +#define CLIENT_H
  3 +
  4 +#include <fcntl.h>
  5 +#include <unistd.h>
  6 +
  7 +#include "threaddata.h"
  8 +
  9 +class ThreadData;
  10 +
  11 +class Client
  12 +{
  13 + int fd;
  14 +
  15 + // maybe read buffer?
  16 +
  17 + ThreadData &threadData;
  18 +
  19 +public:
  20 + Client(int fd, ThreadData &threadData);
  21 + ~Client();
  22 +
  23 + int getFd() { return fd;}
  24 +
  25 +};
  26 +
  27 +typedef std::shared_ptr<Client> Client_p;
  28 +
  29 +#endif // CLIENT_H
... ...
main.cpp
... ... @@ -9,6 +9,7 @@
9 9  
10 10 #include "utils.h"
11 11 #include "threaddata.h"
  12 +#include "client.h"
12 13  
13 14 #define MAX_EVENTS 1024
14 15 #define NR_OF_THREADS 4
... ... @@ -17,7 +18,31 @@
17 18  
18 19 void do_thread_work(ThreadData &threadData)
19 20 {
  21 + int epoll_fd = threadData.epollfd;
20 22  
  23 + struct epoll_event events[MAX_EVENTS];
  24 + memset(&events, 0, sizeof (struct epoll_event)*MAX_EVENTS);
  25 +
  26 + while (1)
  27 + {
  28 + int fdcount = epoll_wait(epoll_fd, events, MAX_EVENTS, 100);
  29 +
  30 + if (fdcount > 0)
  31 + {
  32 + for (int i = 0; i < fdcount; i++)
  33 + {
  34 + struct epoll_event cur_ev = events[i];
  35 + int fd = cur_ev.data.fd;
  36 +
  37 + Client_p client = threadData.getClient(fd);
  38 +
  39 + if (client) // TODO: is this check necessary?
  40 + {
  41 + // TODO left here
  42 + }
  43 + }
  44 + }
  45 + }
21 46 }
22 47  
23 48 int main()
... ... @@ -81,9 +106,8 @@ int main()
81 106 socklen_t len = sizeof(struct sockaddr);
82 107 int fd = check<std::runtime_error>(accept(cur_fd, &addr, &len));
83 108  
84   - // TODO: make client
85   -
86   - thread_data.giveFdToEpoll(fd);
  109 + Client_p client(new Client(fd, thread_data));
  110 + thread_data.giveClient(client);
87 111 }
88 112 else
89 113 {
... ...
threaddata.cpp
... ... @@ -8,11 +8,24 @@ ThreadData::ThreadData(int threadnr) :
8 8 event_fd = eventfd(0, EFD_NONBLOCK);
9 9 }
10 10  
11   -void ThreadData::giveFdToEpoll(int fd)
  11 +void ThreadData::giveClient(Client_p client)
12 12 {
  13 + int fd = client->getFd();
13 14 struct epoll_event ev;
14 15 memset(&ev, 0, sizeof (struct epoll_event));
15 16 ev.data.fd = fd;
16 17 ev.events = EPOLLIN;
17 18 check<std::runtime_error>(epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev));
  19 +
  20 + clients_by_fd[fd] = client;
  21 +}
  22 +
  23 +Client_p ThreadData::getClient(int fd)
  24 +{
  25 + return this->clients_by_fd[fd];
  26 +}
  27 +
  28 +void ThreadData::removeClient(Client_p client)
  29 +{
  30 + clients_by_fd.erase(client->getFd());
18 31 }
... ...
threaddata.h
... ... @@ -5,9 +5,16 @@
5 5 #include "utils.h"
6 6 #include <sys/epoll.h>
7 7 #include <sys/eventfd.h>
  8 +#include "client.h"
  9 +#include <map>
  10 +
  11 +class Client;
  12 +typedef std::shared_ptr<Client> Client_p;
8 13  
9 14 class ThreadData
10 15 {
  16 + std::map<int, Client_p> clients_by_fd;
  17 +
11 18 public:
12 19 std::thread thread;
13 20 int threadnr = 0;
... ... @@ -16,7 +23,9 @@ public:
16 23  
17 24 ThreadData(int threadnr);
18 25  
19   - void giveFdToEpoll(int fd);
  26 + void giveClient(Client_p client);
  27 + Client_p getClient(int fd);
  28 + void removeClient(Client_p client);
20 29 };
21 30  
22 31 #endif // THREADDATA_H
... ...