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
86d4347a
Commit
86d4347a
authored
Feb 28, 2014
by
louiz’
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Avoid unnecessary copies by recv()ing data directly into the expat buffer
parent
df774d45
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
93 additions
and
18 deletions
+93
-18
src/irc/irc_client.cpp
src/irc/irc_client.cpp
+1
-1
src/irc/irc_client.hpp
src/irc/irc_client.hpp
+1
-1
src/network/socket_handler.cpp
src/network/socket_handler.cpp
+21
-5
src/network/socket_handler.hpp
src/network/socket_handler.hpp
+17
-3
src/xmpp/xmpp_component.cpp
src/xmpp/xmpp_component.cpp
+18
-3
src/xmpp/xmpp_component.hpp
src/xmpp/xmpp_component.hpp
+6
-2
src/xmpp/xmpp_parser.cpp
src/xmpp/xmpp_parser.cpp
+20
-2
src/xmpp/xmpp_parser.hpp
src/xmpp/xmpp_parser.hpp
+9
-1
No files found.
src/irc/irc_client.cpp
View file @
86d4347a
...
...
@@ -80,7 +80,7 @@ std::string IrcClient::get_own_nick() const
return
this
->
current_nick
;
}
void
IrcClient
::
parse_in_buffer
()
void
IrcClient
::
parse_in_buffer
(
const
size_t
)
{
while
(
true
)
{
...
...
src/irc/irc_client.hpp
View file @
86d4347a
...
...
@@ -45,7 +45,7 @@ public:
* Parse the data we have received so far and try to get one or more
* complete messages from it.
*/
void
parse_in_buffer
()
override
final
;
void
parse_in_buffer
(
const
size_t
)
override
final
;
/**
* Return the channel with this name, create it if it does not yet exist
*/
...
...
src/network/socket_handler.cpp
View file @
86d4347a
...
...
@@ -138,11 +138,16 @@ void SocketHandler::set_poller(Poller* poller)
this
->
poller
=
poller
;
}
void
SocketHandler
::
on_recv
(
const
size_t
nb
)
void
SocketHandler
::
on_recv
()
{
char
buf
[
4096
];
static
constexpr
size_t
buf_size
=
4096
;
char
buf
[
buf_size
];
void
*
recv_buf
=
this
->
get_receive_buffer
(
buf_size
);
ssize_t
size
=
::
recv
(
this
->
socket
,
buf
,
nb
,
0
);
if
(
recv_buf
==
nullptr
)
recv_buf
=
buf
;
ssize_t
size
=
::
recv
(
this
->
socket
,
recv_buf
,
buf_size
,
0
);
if
(
0
==
size
)
{
this
->
on_connection_close
();
...
...
@@ -156,8 +161,14 @@ void SocketHandler::on_recv(const size_t nb)
}
else
{
this
->
in_buf
+=
std
::
string
(
buf
,
size
);
this
->
parse_in_buffer
();
if
(
buf
==
recv_buf
)
{
// data needs to be placed in the in_buf string, because no buffer
// was provided to receive that data directly. The in_buf buffer
// will be handled in parse_in_buffer()
this
->
in_buf
+=
std
::
string
(
buf
,
size
);
}
this
->
parse_in_buffer
(
size
);
}
}
...
...
@@ -238,3 +249,8 @@ bool SocketHandler::is_connecting() const
{
return
this
->
connecting
;
}
void
*
SocketHandler
::
get_receive_buffer
(
const
size_t
)
const
{
return
nullptr
;
}
src/network/socket_handler.hpp
View file @
86d4347a
...
...
@@ -41,7 +41,7 @@ public:
* Reads data in our in_buf and the call parse_in_buf, for the implementor
* to handle the data received so far.
*/
void
on_recv
(
const
size_t
nb
=
4096
);
void
on_recv
();
/**
* Write as much data from out_buf as possible, in the socket.
*/
...
...
@@ -73,14 +73,28 @@ public:
*/
virtual
void
on_connection_close
()
=
0
;
/**
* Handle/consume (some of) the data received so far. If some data is used, the in_buf
* Handle/consume (some of) the data received so far. The data to handle
* may be in the in_buf buffer, or somewhere else, depending on what
* get_receive_buffer() returned. If some data is used from in_buf, it
* should be truncated, only the unused data should be left untouched.
*
* The size argument is the size of the last chunk of data that was added to the buffer.
*/
virtual
void
parse_in_buffer
()
=
0
;
virtual
void
parse_in_buffer
(
const
size_t
size
)
=
0
;
bool
is_connected
()
const
;
bool
is_connecting
()
const
;
protected:
/**
* Provide a buffer in which data can be directly received. This can be
* used to avoid copying data into in_buf before using it. If no buffer
* can provided, nullptr is returned (the default implementation does
* that).
*/
virtual
void
*
get_receive_buffer
(
const
size_t
size
)
const
;
/**
* The handled socket.
*/
socket_t
socket
;
/**
* Where data read from the socket is added until we can extract a full
...
...
src/xmpp/xmpp_component.cpp
View file @
86d4347a
...
...
@@ -89,10 +89,20 @@ void XmppComponent::on_connection_close()
log_info
(
"XMPP server closed connection"
);
}
void
XmppComponent
::
parse_in_buffer
()
void
XmppComponent
::
parse_in_buffer
(
const
size_t
size
)
{
this
->
parser
.
feed
(
this
->
in_buf
.
data
(),
this
->
in_buf
.
size
(),
false
);
this
->
in_buf
.
clear
();
if
(
!
this
->
in_buf
.
empty
())
{
// This may happen if the parser could not allocate enough space for
// us. We try to feed it the data that was read into our in_buf
// instead. If this fails again we are in trouble.
this
->
parser
.
feed
(
this
->
in_buf
.
data
(),
this
->
in_buf
.
size
(),
false
);
this
->
in_buf
.
clear
();
}
else
{
// Just tell the parser to parse the data that was placed into the
// buffer it provided to us with GetBuffer
this
->
parser
.
parse
(
size
,
false
);
}
}
void
XmppComponent
::
shutdown
()
...
...
@@ -308,6 +318,11 @@ Bridge* XmppComponent::get_user_bridge(const std::string& user_jid)
}
}
void
*
XmppComponent
::
get_receive_buffer
(
const
size_t
size
)
const
{
return
this
->
parser
.
get_buffer
(
size
);
}
void
XmppComponent
::
send_message
(
const
std
::
string
&
from
,
Xmpp
::
body
&&
body
,
const
std
::
string
&
to
)
{
XmlNode
node
(
"message"
);
...
...
src/xmpp/xmpp_component.hpp
View file @
86d4347a
...
...
@@ -23,7 +23,7 @@ public:
void
on_connection_failed
(
const
std
::
string
&
reason
)
override
final
;
void
on_connected
()
override
final
;
void
on_connection_close
()
override
final
;
void
parse_in_buffer
()
override
final
;
void
parse_in_buffer
(
const
size_t
size
)
override
final
;
/**
* Send a "close" message to all our connected peers. That message
* depends on the protocol used (this may be a QUIT irc message, or a
...
...
@@ -142,7 +142,11 @@ private:
* if none already exist.
*/
Bridge
*
get_user_bridge
(
const
std
::
string
&
user_jid
);
/**
* Return a buffer provided by the XML parser, to read data directly into
* it, and avoiding some unnecessary copy.
*/
void
*
get_receive_buffer
(
const
size_t
size
)
const
override
final
;
XmppParser
parser
;
std
::
string
stream_id
;
std
::
string
served_hostname
;
...
...
src/xmpp/xmpp_parser.cpp
View file @
86d4347a
#include <xmpp/xmpp_parser.hpp>
#include <xmpp/xmpp_stanza.hpp>
#include <logger/logger.hpp>
/**
* Expat handlers. Called by the Expat library, never by ourself.
* They just forward the call to the XmppParser corresponding methods.
...
...
@@ -45,9 +47,25 @@ XmppParser::~XmppParser()
XML_ParserFree
(
this
->
parser
);
}
void
XmppParser
::
feed
(
const
char
*
data
,
const
int
len
,
const
bool
is_final
)
int
XmppParser
::
feed
(
const
char
*
data
,
const
int
len
,
const
bool
is_final
)
{
int
res
=
XML_Parse
(
this
->
parser
,
data
,
len
,
is_final
);
if
(
res
==
0
)
log_error
(
"Xml_Parse encountered an error"
);
return
res
;
}
int
XmppParser
::
parse
(
const
int
len
,
const
bool
is_final
)
{
int
res
=
XML_ParseBuffer
(
this
->
parser
,
len
,
is_final
);
if
(
res
==
0
)
log_error
(
"Xml_Parsebuffer encountered an error"
);
return
res
;
}
void
*
XmppParser
::
get_buffer
(
const
size_t
size
)
const
{
XML_Parse
(
this
->
parser
,
data
,
len
,
is_final
);
return
XML_GetBuffer
(
this
->
parser
,
static_cast
<
int
>
(
size
)
);
}
void
XmppParser
::
start_element
(
const
XML_Char
*
name
,
const
XML_Char
**
attribute
)
...
...
src/xmpp/xmpp_parser.hpp
View file @
86d4347a
...
...
@@ -37,7 +37,15 @@ public:
/**
* Feed the parser with some XML data
*/
void
feed
(
const
char
*
data
,
const
int
len
,
const
bool
is_final
);
int
feed
(
const
char
*
data
,
const
int
len
,
const
bool
is_final
);
/**
* Parse the data placed in the parser buffer
*/
int
parse
(
const
int
size
,
const
bool
is_final
);
/**
* Get a buffer provided by the xml parser.
*/
void
*
get_buffer
(
const
size_t
size
)
const
;
/**
* Add one callback for the various events that this parser can spawn.
*/
...
...
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