Socket library optimization.
This commit is contained in:
parent
7ff374ab69
commit
a7fa0eedcb
2 changed files with 38 additions and 8 deletions
|
@ -203,6 +203,12 @@ void setFDBlocking(int FD, bool blocking){
|
||||||
fcntl(FD, F_SETFL, flags);
|
fcntl(FD, F_SETFL, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Internally used call to make an file descriptor blocking or not.
|
||||||
|
bool isFDBlocking(int FD){
|
||||||
|
int flags = fcntl(FD, F_GETFL, 0);
|
||||||
|
return (flags & O_NONBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
/// Set this socket to be blocking (true) or nonblocking (false).
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
void Socket::Connection::setBlocking(bool blocking){
|
void Socket::Connection::setBlocking(bool blocking){
|
||||||
if (sock >= 0){
|
if (sock >= 0){
|
||||||
|
@ -216,6 +222,20 @@ void Socket::Connection::setBlocking(bool blocking){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
|
bool Socket::Connection::isBlocking(){
|
||||||
|
if (sock >= 0){
|
||||||
|
return isFDBlocking(sock);
|
||||||
|
}
|
||||||
|
if (pipes[0] >= 0){
|
||||||
|
return isFDBlocking(pipes[0]);
|
||||||
|
}
|
||||||
|
if (pipes[1] >= 0){
|
||||||
|
return isFDBlocking(pipes[1]);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Close connection. The internal socket is closed and then set to -1.
|
/// Close connection. The internal socket is closed and then set to -1.
|
||||||
/// If the connection is already closed, nothing happens.
|
/// If the connection is already closed, nothing happens.
|
||||||
void Socket::Connection::close(){
|
void Socket::Connection::close(){
|
||||||
|
@ -383,9 +403,12 @@ std::string Socket::Connection::getStats(std::string C){
|
||||||
/// Updates the downbuffer and upbuffer internal variables.
|
/// Updates the downbuffer and upbuffer internal variables.
|
||||||
/// Returns true if new data was received, false otherwise.
|
/// Returns true if new data was received, false otherwise.
|
||||||
bool Socket::Connection::spool(){
|
bool Socket::Connection::spool(){
|
||||||
|
bool bing = isBlocking();
|
||||||
|
if (!bing){setBlocking(true);}
|
||||||
if (upbuffer.size() > 0){
|
if (upbuffer.size() > 0){
|
||||||
iwrite(upbuffer.get());
|
iwrite(upbuffer.get());
|
||||||
}
|
}
|
||||||
|
if (!bing){setBlocking(false);}
|
||||||
/// \todo Provide better mechanism to prevent overbuffering.
|
/// \todo Provide better mechanism to prevent overbuffering.
|
||||||
if (downbuffer.size() > 10000){
|
if (downbuffer.size() > 10000){
|
||||||
return true;
|
return true;
|
||||||
|
@ -397,11 +420,12 @@ bool Socket::Connection::spool(){
|
||||||
/// Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
/// Updates the downbuffer and upbuffer internal variables until upbuffer is empty.
|
||||||
/// Returns true if new data was received, false otherwise.
|
/// Returns true if new data was received, false otherwise.
|
||||||
bool Socket::Connection::flush(){
|
bool Socket::Connection::flush(){
|
||||||
|
bool bing = isBlocking();
|
||||||
|
if (!bing){setBlocking(true);}
|
||||||
while (upbuffer.size() > 0 && connected()){
|
while (upbuffer.size() > 0 && connected()){
|
||||||
if ( !iwrite(upbuffer.get())){
|
iwrite(upbuffer.get());
|
||||||
Util::sleep(10); //sleep 10ms
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (!bing){setBlocking(false);}
|
||||||
/// \todo Provide better mechanism to prevent overbuffering.
|
/// \todo Provide better mechanism to prevent overbuffering.
|
||||||
if (downbuffer.size() > 1000){
|
if (downbuffer.size() > 1000){
|
||||||
return true;
|
return true;
|
||||||
|
@ -420,17 +444,13 @@ Socket::Buffer & Socket::Connection::Received(){
|
||||||
/// Any data that could not be send will block until it can be send or the connection is severed.
|
/// Any data that could not be send will block until it can be send or the connection is severed.
|
||||||
void Socket::Connection::SendNow(const char * data, size_t len){
|
void Socket::Connection::SendNow(const char * data, size_t len){
|
||||||
while (upbuffer.size() > 0 && connected()){
|
while (upbuffer.size() > 0 && connected()){
|
||||||
if ( !iwrite(upbuffer.get())){
|
iwrite(upbuffer.get());
|
||||||
Util::sleep(1); //sleep 1ms if buffer full
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
int i = iwrite(data, len);
|
int i = iwrite(data, len);
|
||||||
while (i < len && connected()){
|
while (i < len && connected()){
|
||||||
int j = iwrite(data + i, std::min(len - i, (size_t)51200));
|
int j = iwrite(data + i, std::min(len - i, (size_t)51200));
|
||||||
if (j > 0){
|
if (j > 0){
|
||||||
i += j;
|
i += j;
|
||||||
}else{
|
|
||||||
Util::sleep(1); //sleep 1ms and retry
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -862,6 +882,14 @@ void Socket::Server::setBlocking(bool blocking){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set this socket to be blocking (true) or nonblocking (false).
|
||||||
|
bool Socket::Server::isBlocking(){
|
||||||
|
if (sock >= 0){
|
||||||
|
return isFDBlocking(sock);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// Close connection. The internal socket is closed and then set to -1.
|
/// Close connection. The internal socket is closed and then set to -1.
|
||||||
/// If the connection is already closed, nothing happens.
|
/// If the connection is already closed, nothing happens.
|
||||||
void Socket::Server::close(){
|
void Socket::Server::close(){
|
||||||
|
|
|
@ -69,6 +69,7 @@ namespace Socket {
|
||||||
//generic methods
|
//generic methods
|
||||||
void close(); ///< Close connection.
|
void close(); ///< Close connection.
|
||||||
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
||||||
|
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
||||||
std::string getHost(); ///< Gets hostname for connection, if available.
|
std::string getHost(); ///< Gets hostname for connection, if available.
|
||||||
void setHost(std::string host); ///< Sets hostname for connection manually.
|
void setHost(std::string host); ///< Sets hostname for connection manually.
|
||||||
int getSocket(); ///< Returns internal socket number.
|
int getSocket(); ///< Returns internal socket number.
|
||||||
|
@ -111,6 +112,7 @@ namespace Socket {
|
||||||
Connection accept(bool nonblock = false); ///< Accept any waiting connections.
|
Connection accept(bool nonblock = false); ///< Accept any waiting connections.
|
||||||
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
void setBlocking(bool blocking); ///< Set this socket to be blocking (true) or nonblocking (false).
|
||||||
bool connected() const; ///< Returns the connected-state for this socket.
|
bool connected() const; ///< Returns the connected-state for this socket.
|
||||||
|
bool isBlocking(); ///< Check if this socket is blocking (true) or nonblocking (false).
|
||||||
void close(); ///< Close connection.
|
void close(); ///< Close connection.
|
||||||
int getSocket(); ///< Returns internal socket number.
|
int getSocket(); ///< Returns internal socket number.
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue