Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
biboumi
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
88
Issues
88
List
Boards
Labels
Service Desk
Milestones
Merge Requests
7
Merge Requests
7
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
louiz’
biboumi
Commits
70a58a8f
Commit
70a58a8f
authored
Nov 21, 2013
by
louiz’
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'epolletc'
parents
e7a441e7
b7290854
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
135 additions
and
17 deletions
+135
-17
CMakeLists.txt
CMakeLists.txt
+7
-1
config.h.cmake
config.h.cmake
+1
-0
src/irc/irc_client.cpp
src/irc/irc_client.cpp
+21
-0
src/irc/irc_client.hpp
src/irc/irc_client.hpp
+23
-2
src/network/poller.cpp
src/network/poller.cpp
+69
-4
src/network/poller.hpp
src/network/poller.hpp
+14
-10
No files found.
CMakeLists.txt
View file @
70a58a8f
...
...
@@ -24,6 +24,12 @@ include_directories(${ICONV_INCLUDE_DIR})
# coming from these headers.
include_directories
(
SYSTEM
${
CRYPTO++_INCLUDE_DIR
}
)
set
(
POLLER
"POLL"
CACHE STRING
"Choose the poller between POLL and EPOLL (Linux-only)"
)
if
((
NOT
${
POLLER
}
MATCHES
"POLL"
)
AND
(
NOT
${
POLLER
}
MATCHES
"EPOLL"
))
message
(
FATAL_ERROR
"POLLER must be either POLL or EPOLL"
)
endif
()
#
## utils
#
...
...
@@ -95,4 +101,4 @@ target_link_libraries(test
utils
config
)
CONFIGURE_FILE
(
config.h.cmake src/config.h @ONLY
)
configure_file
(
config.h.cmake src/config.h
)
config.h.cmake
View file @
70a58a8f
#cmakedefine ICONV_SECOND_ARGUMENT_IS_CONST
#cmakedefine POLLER ${POLLER}
src/irc/irc_client.cpp
View file @
70a58a8f
...
...
@@ -222,6 +222,27 @@ void IrcClient::on_channel_message(const IrcMessage& message)
this
->
bridge
->
send_message
(
iid
,
nick
,
body
,
muc
);
}
void
IrcClient
::
empty_motd
(
const
IrcMessage
&
message
)
{
(
void
)
message
;
this
->
motd
.
erase
();
}
void
IrcClient
::
on_motd_line
(
const
IrcMessage
&
message
)
{
const
std
::
string
body
=
message
.
arguments
[
1
];
// We could send the MOTD without a line break between each IRC-message,
// but sometimes it contains some ASCII art, we use line breaks to keep
// them intact.
this
->
motd
+=
body
+
"
\n
"
;
}
void
IrcClient
::
send_motd
(
const
IrcMessage
&
message
)
{
(
void
)
message
;
this
->
bridge
->
send_xmpp_message
(
this
->
hostname
,
""
,
this
->
motd
);
}
void
IrcClient
::
on_topic_received
(
const
IrcMessage
&
message
)
{
const
std
::
string
chan_name
=
message
.
arguments
[
1
];
...
...
src/irc/irc_client.hpp
View file @
70a58a8f
...
...
@@ -99,6 +99,18 @@ public:
* Forward the server message received from IRC to the XMPP component
*/
void
forward_server_message
(
const
IrcMessage
&
message
);
/**
* Just empty the motd we kept as a string
*/
void
empty_motd
(
const
IrcMessage
&
message
);
/**
* Send the MOTD string as one single "big" message
*/
void
send_motd
(
const
IrcMessage
&
message
);
/**
* Append this line to the MOTD
*/
void
on_motd_line
(
const
IrcMessage
&
message
);
/**
* Forward the join of an other user into an IRC channel, and save the
* IrcUsers in the IrcChannel
...
...
@@ -172,6 +184,11 @@ private:
*/
std
::
vector
<
std
::
string
>
channels_to_join
;
bool
welcomed
;
/**
* Each motd line received is appended to this string, which we send when
* the motd is completely received
*/
std
::
string
motd
;
IrcClient
(
const
IrcClient
&
)
=
delete
;
IrcClient
(
IrcClient
&&
)
=
delete
;
IrcClient
&
operator
=
(
const
IrcClient
&
)
=
delete
;
...
...
@@ -186,8 +203,12 @@ typedef void (IrcClient::*irc_callback_t)(const IrcMessage&);
static
const
std
::
unordered_map
<
std
::
string
,
irc_callback_t
>
irc_callbacks
=
{
{
"NOTICE"
,
&
IrcClient
::
forward_server_message
},
{
"375"
,
&
IrcClient
::
forward_server_message
},
{
"372"
,
&
IrcClient
::
forward_server_message
},
{
"RPL_MOTDSTART"
,
&
IrcClient
::
empty_motd
},
{
"375"
,
&
IrcClient
::
empty_motd
},
{
"RPL_MOTD"
,
&
IrcClient
::
on_motd_line
},
{
"372"
,
&
IrcClient
::
on_motd_line
},
{
"RPL_MOTDEND"
,
&
IrcClient
::
send_motd
},
{
"376"
,
&
IrcClient
::
send_motd
},
{
"JOIN"
,
&
IrcClient
::
on_channel_join
},
{
"PRIVMSG"
,
&
IrcClient
::
on_channel_message
},
{
"353"
,
&
IrcClient
::
set_and_forward_user_list
},
...
...
src/network/poller.cpp
View file @
70a58a8f
...
...
@@ -12,6 +12,13 @@ Poller::Poller()
#if POLLER == POLL
memset
(
this
->
fds
,
0
,
sizeof
(
this
->
fds
));
this
->
nfds
=
0
;
#elif POLLER == EPOLL
this
->
epfd
=
::
epoll_create1
(
0
);
if
(
this
->
epfd
==
-
1
)
{
perror
(
"epoll"
);
throw
std
::
runtime_error
(
"Could not create epoll instance"
);
}
#endif
}
...
...
@@ -36,6 +43,17 @@ void Poller::add_socket_handler(std::shared_ptr<SocketHandler> socket_handler)
this
->
fds
[
this
->
nfds
].
events
=
POLLIN
;
this
->
nfds
++
;
#endif
#if POLLER == EPOLL
struct
epoll_event
event
;
event
.
data
.
ptr
=
socket_handler
.
get
();
event
.
events
=
EPOLLIN
;
const
int
res
=
::
epoll_ctl
(
this
->
epfd
,
EPOLL_CTL_ADD
,
socket_handler
->
get_socket
(),
&
event
);
if
(
res
==
-
1
)
{
perror
(
"epoll_ctl"
);
throw
std
::
runtime_error
(
"Could not add socket to epoll"
);
}
#endif
}
void
Poller
::
remove_socket_handler
(
const
socket_t
socket
)
...
...
@@ -44,6 +62,8 @@ void Poller::remove_socket_handler(const socket_t socket)
if
(
it
==
this
->
socket_handlers
.
end
())
throw
std
::
runtime_error
(
"Trying to remove a SocketHandler that is not managed"
);
this
->
socket_handlers
.
erase
(
it
);
#if POLLER == POLL
for
(
size_t
i
=
0
;
i
<
this
->
nfds
;
i
++
)
{
if
(
this
->
fds
[
i
].
fd
==
socket
)
...
...
@@ -58,9 +78,17 @@ void Poller::remove_socket_handler(const socket_t socket)
this
->
nfds
--
;
}
}
#elif POLLER == EPOLL
const
int
res
=
::
epoll_ctl
(
this
->
epfd
,
EPOLL_CTL_DEL
,
socket
,
nullptr
);
if
(
res
==
-
1
)
{
perror
(
"epoll_ctl"
);
throw
std
::
runtime_error
(
"Could not remove socket from epoll"
);
}
#endif
}
void
Poller
::
watch_send_events
(
const
SocketHandler
*
const
socket_handler
)
void
Poller
::
watch_send_events
(
SocketHandler
*
socket_handler
)
{
#if POLLER == POLL
for
(
size_t
i
=
0
;
i
<=
this
->
nfds
;
++
i
)
...
...
@@ -71,11 +99,21 @@ void Poller::watch_send_events(const SocketHandler* const socket_handler)
return
;
}
}
#endif
throw
std
::
runtime_error
(
"Cannot watch a non-registered socket for send events"
);
#elif POLLER == EPOLL
struct
epoll_event
event
;
event
.
data
.
ptr
=
socket_handler
;
event
.
events
=
EPOLLIN
|
EPOLLOUT
;
const
int
res
=
::
epoll_ctl
(
this
->
epfd
,
EPOLL_CTL_MOD
,
socket_handler
->
get_socket
(),
&
event
);
if
(
res
==
-
1
)
{
perror
(
"epoll_ctl"
);
throw
std
::
runtime_error
(
"Could not modify socket flags in epoll"
);
}
#endif
}
void
Poller
::
stop_watching_send_events
(
const
SocketHandler
*
const
socket_handler
)
void
Poller
::
stop_watching_send_events
(
SocketHandler
*
socket_handler
)
{
#if POLLER == POLL
for
(
size_t
i
=
0
;
i
<=
this
->
nfds
;
++
i
)
...
...
@@ -86,8 +124,18 @@ void Poller::stop_watching_send_events(const SocketHandler* const socket_handler
return
;
}
}
#endif
throw
std
::
runtime_error
(
"Cannot watch a non-registered socket for send events"
);
#elif POLLER == EPOLL
struct
epoll_event
event
;
event
.
data
.
ptr
=
socket_handler
;
event
.
events
=
EPOLLIN
;
const
int
res
=
::
epoll_ctl
(
this
->
epfd
,
EPOLL_CTL_MOD
,
socket_handler
->
get_socket
(),
&
event
);
if
(
res
==
-
1
)
{
perror
(
"epoll_ctl"
);
throw
std
::
runtime_error
(
"Could not modify socket flags in epoll"
);
}
#endif
}
bool
Poller
::
poll
()
...
...
@@ -121,6 +169,23 @@ bool Poller::poll()
res
--
;
}
}
#elif POLLER == EPOLL
static
const
size_t
max_events
=
12
;
struct
epoll_event
revents
[
max_events
];
const
int
nb_events
=
epoll_wait
(
this
->
epfd
,
revents
,
max_events
,
-
1
);
if
(
nb_events
==
-
1
)
{
perror
(
"epoll_wait"
);
throw
std
::
runtime_error
(
"Epoll_wait failed"
);
}
for
(
int
i
=
0
;
i
<
nb_events
;
++
i
)
{
auto
socket_handler
=
static_cast
<
SocketHandler
*>
(
revents
[
i
].
data
.
ptr
);
if
(
revents
[
i
].
events
&
EPOLLIN
)
socket_handler
->
on_recv
();
if
(
revents
[
i
].
events
&
EPOLLOUT
)
socket_handler
->
on_send
();
}
#endif
return
true
;
}
src/network/poller.hpp
View file @
70a58a8f
...
...
@@ -9,27 +9,29 @@
#define POLL 1
#define EPOLL 2
#define KQUEUE 3
#define POLLER POLL
#include <config.h>
#ifndef POLLER
#define POLLER POLL
#endif
#if POLLER == POLL
#include <poll.h>
// TODO, dynamic size, without artificial limit
#define MAX_POLL_FD_NUMBER 4096
#elif POLLER == EPOLL
#include <sys/epoll.h>
#else
#error Invalid POLLER value
#endif
/**
* We pass some SocketHandlers to this
the
Poller, which uses
* We pass some SocketHandlers to this Poller, which uses
* poll/epoll/kqueue/select etc to wait for events on these SocketHandlers,
* and call the callbacks when event occurs.
*
* TODO: support for all these pollers:
* - poll(2) (mandatory)
* - epoll(7)
* TODO: support these pollers:
* - kqueue(2)
*/
class
Poller
{
public:
...
...
@@ -48,12 +50,12 @@ public:
* Signal the poller that he needs to watch for send events for the given
* SocketHandler.
*/
void
watch_send_events
(
const
SocketHandler
*
const
socket_handler
);
void
watch_send_events
(
SocketHandler
*
socket_handler
);
/**
* Signal the poller that he needs to stop watching for send events for
* this SocketHandler.
*/
void
stop_watching_send_events
(
const
SocketHandler
*
const
socket_handler
);
void
stop_watching_send_events
(
SocketHandler
*
socket_handler
);
/**
* Wait for all watched events, and call the SocketHandlers' callbacks
* when one is ready.
...
...
@@ -72,6 +74,8 @@ private:
#if POLLER == POLL
struct
pollfd
fds
[
MAX_POLL_FD_NUMBER
];
nfds_t
nfds
;
#elif POLLER == EPOLL
int
epfd
;
#endif
Poller
(
const
Poller
&
)
=
delete
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment