Skip to content

Commit

Permalink
Windows port and fixes (Cylix#1)
Browse files Browse the repository at this point in the history
* start port to windows. now compile but code need to be improve to ensure better separation between unix & windows parts. cpp_redis tests do not pass for now.

* reorganize repository to separate windows and unix code

* windows compilation after code reorganization

* small timeout on WSAPoll, use windows versions of POLLIN POLLOUt

* fix unix compilation & listen to PULLHUP event

* fix io_service causing idle when waiting for sockets to be removed. Set WSAPoll timeout to -1. Clean code

* unix compilation warning fix && clang-format

* port windows fix to unix (io_service idle / POLLHUP / ...)

* update cmakelist for windows cpp_redis integration

* fix Cmake warnings under unix (cpp_redis integration)

* install_deps update

* try fix travis

* try fix travis

* fix cmakelist

* fix cmakelist

* fix cmakelist
  • Loading branch information
Cylix committed Jan 29, 2017
1 parent e1de5f2 commit 5526907
Show file tree
Hide file tree
Showing 16 changed files with 924 additions and 106 deletions.
48 changes: 33 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The MIT License (MIT)
#
# Copyright (c) 2015-2017 Simon Ninon <simon.ninon@gmail.com>
# Copyright (c) 2016-2017 Simon Ninon <simon.ninon@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
Expand Down Expand Up @@ -43,19 +43,29 @@ project(${PROJECT} CXX)
###
# compilation options
###
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -W -Wall -Wextra -O3")
IF (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3 /O2")

# was causing conflics with gtest build
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
foreach (flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE)
string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}")
endforeach()

add_definitions(-D_UNICODE)
add_definitions(-DUNICODE)
add_definitions(-DWIN32_LEAN_AND_MEAN)
ELSE ()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -W -Wall -Wextra -O3")
ENDIF (WIN32)


###
# variables
###
set(DEPS_FOLDER ${PROJECT_SOURCE_DIR}/deps/build)
IF (NOT GTEST_INCLUDES)
set(GTEST_INCLUDES ${DEPS_FOLDER}/gtest/include)
set(GTEST_INCLUDES ${PROJECT_SOURCE_DIR}/deps/src/googletest/googletest/include)
ENDIF (NOT GTEST_INCLUDES)
IF (NOT GTEST_LIBS)
set(GTEST_LIBS ${DEPS_FOLDER}/gtest/lib)
ENDIF (NOT GTEST_LIBS)
set(TACOPIE_INCLUDES ${PROJECT_SOURCE_DIR}/includes)


Expand All @@ -64,17 +74,17 @@ set(TACOPIE_INCLUDES ${PROJECT_SOURCE_DIR}/includes)
###
include_directories(${TACOPIE_INCLUDES})


###
# link
###
link_directories(${GTEST_LIBS})


###
# sources
###
set(SRC_DIRS "sources" "sources/network" "sources/utils" "includes/tacopie" "includes/tacopie/network" "includes/tacopie/utils")

IF (WIN32)
set(SRC_DIRS ${SRC_DIRS} "sources/network/windows" "includes/tacopie/network/windows")
ELSE ()
set(SRC_DIRS ${SRC_DIRS} "sources/network/unix" "includes/tacopie/network/unix")
ENDIF (WIN32)

foreach(dir ${SRC_DIRS})
# get directory sources and headers
file(GLOB s_${dir} "${dir}/*.cpp")
Expand All @@ -98,7 +108,12 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
# executable
###
add_library(${PROJECT} STATIC ${SOURCES})
target_link_libraries(${PROJECT} pthread)

IF (WIN32)
target_link_libraries(${PROJECT} ws2_32)
ELSE ()
target_link_libraries(${PROJECT} pthread)
ENDIF (WIN32)

# __TACOPIE_LOGGING_ENABLED
IF (LOGGING_ENABLED)
Expand Down Expand Up @@ -137,4 +152,7 @@ ENDIF(BUILD_EXAMPLES)
###
IF (BUILD_TESTS)
add_subdirectory(tests)
IF (EXISTS ${PROJECT_SOURCE_DIR}/deps/src/googletest)
add_subdirectory(${PROJECT_SOURCE_DIR}/deps/src/googletest)
ENDIF ()
ENDIF(BUILD_TESTS)
2 changes: 2 additions & 0 deletions includes/tacopie/error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <stdexcept>
#include <string>

#include <tacopie/logger.hpp>

namespace tacopie {

class tacopie_error : public std::runtime_error {
Expand Down
14 changes: 8 additions & 6 deletions includes/tacopie/network/io_service.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@
#include <unordered_map>
#include <vector>

#ifdef _WIN32
#include <Winsock2.h>
#else
#include <poll.h>
#endif /* _WIN32 */

#include <tacopie/network/self_pipe.hpp>
#include <tacopie/network/tcp_socket.hpp>
#include <tacopie/utils/thread_pool.hpp>

Expand Down Expand Up @@ -63,9 +68,6 @@ class io_service {
void set_wr_callback(const tcp_socket& socket, const event_callback_t& event_callback);
void untrack(const tcp_socket& socket);

//! force poll to wake-up
void wake_up(void);

//! wait until the socket has been effectively removed
//! basically wait until all pending callbacks are executed
void wait_for_removal(const tcp_socket& socket);
Expand All @@ -79,7 +81,8 @@ class io_service {
: rd_callback(nullptr)
, is_executing_rd_callback(false)
, wr_callback(nullptr)
, is_executing_wr_callback(false) {}
, is_executing_wr_callback(false)
, marked_for_untrack(false) {}

//! rd event
event_callback_t rd_callback;
Expand All @@ -102,7 +105,6 @@ class io_service {

//! process poll detected events
void process_events(void);
void process_wake_up_event(void);
void process_rd_event(const struct pollfd& poll_result, tracked_socket& socket);
void process_wr_event(const struct pollfd& poll_result, tracked_socket& socket);

Expand All @@ -129,7 +131,7 @@ class io_service {
std::condition_variable m_wait_for_removal_condvar;

//! fd associated to the pipe used to wake up the poll call
int m_notif_pipe_fds[2];
tacopie::self_pipe m_notifier;
};

//! default io_service getter & setter
Expand Down
60 changes: 60 additions & 0 deletions includes/tacopie/network/self_pipe.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// MIT License
//
// Copyright (c) 2016-2017 Simon Ninon <simon.ninon@gmail.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#pragma once

#include <tacopie/typedefs.hpp>

namespace tacopie {

class self_pipe {
public:
//! ctor & dtor
self_pipe(void);
~self_pipe(void);

//! copy ctor & assignment operator
self_pipe(const self_pipe&) = delete;
self_pipe& operator=(const self_pipe&) = delete;

public:
//! get rd/wr fds
fd_t get_read_fd(void) const;
fd_t get_write_fd(void) const;

//! notify
void notify(void);

//! clr buffer
void clr_buffer(void);

private:
#ifdef _WIN32
fd_t m_fd;
struct sockaddr m_addr;
int m_addr_len;
#else
fd_t m_fds[2];
#endif /* _WIN32 */
};

} //! tacopie
16 changes: 16 additions & 0 deletions includes/tacopie/typedefs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,25 @@

#pragma once

#ifdef _WIN32
#include <Winsock2.h>
#endif /* _WIN32 */

namespace tacopie {

//! file descriptor platform type
#ifdef _WIN32
typedef SOCKET fd_t;
#define __TACOPIE_INVALID_FD INVALID_SOCKET
#else
typedef int fd_t;
#define __TACOPIE_INVALID_FD -1
#endif /* _WIN32 */

//! ssize_t
#if defined(_MSC_VER)
#include <BaseTsd.h>
typedef SSIZE_T ssize_t;
#endif

} //! tacopie
8 changes: 2 additions & 6 deletions install_deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@

DEPS_DIR=`pwd`/deps
DEPS_SRC_DIR=$DEPS_DIR/src
DEPS_BUILD_DIR=$DEPS_DIR/build

# Create deps folder
mkdir -p $DEPS_SRC_DIR $DEPS_BUILD_DIR
mkdir -p $DEPS_SRC_DIR

# GoogleTest
cd $DEPS_SRC_DIR
## Fetch the GoogleTest sources
git clone https://github.com/google/googletest.git && cd googletest/googletest && \
mkdir build && cd build && \
cmake .. -DCMAKE_INSTALL_PREFIX=$DEPS_BUILD_DIR/gtest && \
make && make install
git clone https://github.com/google/googletest.git
12 changes: 6 additions & 6 deletions sources/network/tcp_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ tcp_client::connect(const std::string& host, std::uint32_t port) {

void
tcp_client::disconnect(bool wait_for_removal) {
if (not is_connected()) { return; }
if (!is_connected()) { return; }

m_is_connected = false;

Expand Down Expand Up @@ -105,14 +105,14 @@ tcp_client::on_read_available(fd_t) {
read_result result;
auto callback = process_read(result);

if (not result.success) {
if (!result.success) {
__TACOPIE_LOG(warn, "read operation failure");
disconnect();
}

if (callback) { callback(result); }

if (not result.success) { call_disconnection_handler(); }
if (!result.success) { call_disconnection_handler(); }
}

//!
Expand All @@ -126,14 +126,14 @@ tcp_client::on_write_available(fd_t) {
write_result result;
auto callback = process_write(result);

if (not result.success) {
if (!result.success) {
__TACOPIE_LOG(warn, "write operation failure");
disconnect();
}

if (callback) { callback(result); }

if (not result.success) { call_disconnection_handler(); }
if (!result.success) { call_disconnection_handler(); }
}

//!
Expand Down Expand Up @@ -260,7 +260,7 @@ tcp_client::operator==(const tcp_client& rhs) const {

bool
tcp_client::operator!=(const tcp_client& rhs) const {
return not operator==(rhs);
return !operator==(rhs);
}

} //! tacopie
6 changes: 3 additions & 3 deletions sources/network/tcp_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ tcp_server::start(const std::string& host, std::uint32_t port, const on_new_conn

void
tcp_server::stop(void) {
if (not is_running()) { return; }
if (!is_running()) { return; }

m_is_running = false;

Expand Down Expand Up @@ -113,7 +113,7 @@ void
tcp_server::on_client_disconnected(const std::shared_ptr<tcp_client>& client) {
//! If we are not running the server
//! Then it means that this function is called by tcp_client::disconnect() at the destruction of all clients
if (not is_running()) { return; }
if (!is_running()) { return; }

__TACOPIE_LOG(debug, "handle server's client disconnection");

Expand Down Expand Up @@ -165,7 +165,7 @@ tcp_server::operator==(const tcp_server& rhs) const {

bool
tcp_server::operator!=(const tcp_server& rhs) const {
return not operator==(rhs);
return !operator==(rhs);
}

} //! tacopie
Loading

0 comments on commit 5526907

Please sign in to comment.