Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
actor-incubator
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
actor-incubator
Commits
8c1724a8
Commit
8c1724a8
authored
Jul 03, 2019
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add scaffold for socket abstractions
parent
8325b104
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
504 additions
and
0 deletions
+504
-0
libcaf_net/CMakeLists.txt
libcaf_net/CMakeLists.txt
+53
-0
libcaf_net/caf/detail/net_syscall.hpp
libcaf_net/caf/detail/net_syscall.hpp
+43
-0
libcaf_net/caf/detail/socket_sys_includes.hpp
libcaf_net/caf/detail/socket_sys_includes.hpp
+53
-0
libcaf_net/caf/net/abstract_socket.hpp
libcaf_net/caf/net/abstract_socket.hpp
+65
-0
libcaf_net/caf/net/socket.hpp
libcaf_net/caf/net/socket.hpp
+78
-0
libcaf_net/caf/net/socket_id.hpp
libcaf_net/caf/net/socket_id.hpp
+50
-0
libcaf_net/src/socket.cpp
libcaf_net/src/socket.cpp
+129
-0
libcaf_net/test/socket.cpp
libcaf_net/test/socket.cpp
+33
-0
No files found.
libcaf_net/CMakeLists.txt
0 → 100644
View file @
8c1724a8
cmake_minimum_required
(
VERSION 2.8.12
)
project
(
caf_net C CXX
)
# get header files; only needed by CMake generators,
# e.g., for creating proper Xcode projects
file
(
GLOB_RECURSE LIBCAF_NET_HDRS
"caf/*.hpp"
)
# list cpp files excluding platform-dependent files
set
(
LIBCAF_NET_SRCS
src/socket.cpp
)
add_custom_target
(
libcaf_net
)
# build shared library if not compiling static only
if
(
NOT CAF_BUILD_STATIC_ONLY
)
add_library
(
libcaf_net_shared SHARED
${
LIBCAF_NET_SRCS
}
${
LIBCAF_NET_HDRS
}
)
target_link_libraries
(
libcaf_net_shared
${
CAF_EXTRA_LDFLAGS
}
${
CAF_LIBRARY_CORE
}
)
target_include_directories
(
libcaf_net_shared PUBLIC
$<BUILD_INTERFACE:
${
CMAKE_CURRENT_BINARY_DIR
}
>
$<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
>
$<INSTALL_INTERFACE:include>
)
set_target_properties
(
libcaf_net_shared
PROPERTIES
SOVERSION
${
CAF_VERSION
}
VERSION
${
CAF_VERSION
}
OUTPUT_NAME caf_net
)
install
(
TARGETS libcaf_net_shared
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
)
add_dependencies
(
libcaf_net_shared libcaf_net
)
endif
()
# build static library only if --build-static or --build-static-only was set
if
(
CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC
)
add_library
(
libcaf_net_static STATIC
${
LIBCAF_NET_HDRS
}
${
LIBCAF_NET_SRCS
}
)
target_link_libraries
(
libcaf_net_static
${
CAF_EXTRA_LDFLAGS
}
${
CAF_LIBRARY_CORE_STATIC
}
)
target_include_directories
(
libcaf_net_static PUBLIC
$<BUILD_INTERFACE:
${
CMAKE_CURRENT_BINARY_DIR
}
>
$<BUILD_INTERFACE:
${
CMAKE_CURRENT_SOURCE_DIR
}
>
$<INSTALL_INTERFACE:include>
)
set_target_properties
(
libcaf_net_static PROPERTIES OUTPUT_NAME caf_net_static
)
install
(
TARGETS libcaf_net_static ARCHIVE DESTINATION lib
)
add_dependencies
(
libcaf_net_static libcaf_net
)
endif
()
install
(
DIRECTORY
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/caf"
DESTINATION include
FILES_MATCHING PATTERN
"*.hpp"
)
libcaf_net/caf/detail/net_syscall.hpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstdio>
#include <cstdlib>
#include "caf/error.hpp"
#include "caf/sec.hpp"
/// Calls a C functions and returns an error if `var op rhs` returns `true`.
#define CAF_NET_SYSCALL(funname, var, op, rhs, expr) \
auto var = expr; \
if (var op rhs) \
return make_error(sec::network_syscall_failed, funname, \
last_socket_error_as_string())
/// Calls a C functions and calls exit() if `var op rhs` returns `true`.
#define CAF_NET_CRITICAL_SYSCALL(funname, var, op, rhs, expr) \
auto var = expr; \
if (var op rhs) { \
fprintf(stderr, "[FATAL] %s:%u: syscall failed: %s returned %s\n", \
__FILE__, __LINE__, funname, \
last_socket_error_as_string().c_str()); \
abort(); \
} \
static_cast<void>(0)
libcaf_net/caf/detail/socket_sys_includes.hpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
// This convenience header pulls in platform-specific headers for the C socket
// API. Do *not* include this header in other headers.
#pragma once
#include "caf/config.hpp"
#ifdef CAF_WINDOWS
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# endif // CAF_WINDOWS
# ifndef NOMINMAX
# define NOMINMAX
# endif // NOMINMAX
# ifdef CAF_MINGW
# undef _WIN32_WINNT
# undef WINVER
# define _WIN32_WINNT WindowsVista
# define WINVER WindowsVista
# include <w32api.h>
# endif // CAF_MINGW
# include <windows.h>
# include <winsock2.h>
# include <ws2ipdef.h>
# include <ws2tcpip.h>
#else // CAF_WINDOWS
# include <arpa/inet.h>
# include <cerrno>
# include <fcntl.h>
# include <netinet/in.h>
# include <netinet/ip.h>
# include <netinet/tcp.h>
# include <sys/socket.h>
# include <unistd.h>
#endif
libcaf_net/caf/net/abstract_socket.hpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstddef>
#include <limits>
#include "caf/net/socket_id.hpp"
namespace
caf
{
namespace
net
{
template
<
class
Derived
>
struct
abstract_socket
{
socket_id
id
;
constexpr
abstract_socket
(
socket_id
id
)
:
id
(
id
)
{
// nop
}
constexpr
abstract_socket
(
const
Derived
&
other
)
:
id
(
other
.
id
)
{
// nop
}
abstract_socket
&
operator
=
(
const
Derived
&
other
)
{
id
=
other
.
id
;
return
*
this
;
}
template
<
class
Inspector
>
friend
typename
Inspector
::
result_type
inspect
(
Inspector
&
f
,
Derived
&
x
)
{
return
f
(
x
.
id
);
}
friend
constexpr
bool
operator
==
(
Derived
x
,
Derived
y
)
{
return
x
.
id
==
y
.
id
;
}
friend
constexpr
bool
operator
!=
(
Derived
x
,
Derived
y
)
{
return
x
.
id
!=
y
.
id
;
}
friend
constexpr
bool
operator
<
(
Derived
x
,
Derived
y
)
{
return
x
.
id
<
y
.
id
;
}
};
}
// namespace net
}
// namespace caf
libcaf_net/caf/net/socket.hpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <string>
#include <type_traits>
#include "caf/config.hpp"
#include "caf/fwd.hpp"
#include "caf/net/abstract_socket.hpp"
#include "caf/net/socket_id.hpp"
namespace
caf
{
namespace
net
{
/// An internal endpoint for sending or receiving data. Can be either a
/// ::network_socket or a ::pipe_socket.
struct
socket
:
abstract_socket
<
socket
>
{
using
super
=
abstract_socket
<
socket
>
;
using
super
::
super
;
};
/// Denotes the invalid socket.
constexpr
auto
invalid_socket
=
socket
{
invalid_socket_id
};
/// Close socket `x`.
/// @relates socket
void
close
(
socket
x
);
/// Returns the last socket error in this thread as an integer.
/// @relates socket
int
last_socket_error
();
/// Returns the last socket error as human-readable string.
/// @relates socket
std
::
string
last_socket_error_as_string
();
/// Returns a human-readable string for a given socket error.
/// @relates socket
std
::
string
socket_error_as_string
(
int
errcode
);
/// Returns whether `errcode` indicates that an operation would block or return
/// nothing at the moment and can be tried again at a later point.
/// @relates socket
bool
would_block_or_temporarily_unavailable
(
int
errcode
);
/// Sets x to be inherited by child processes if `new_value == true`
/// or not if `new_value == false`. Not implemented on Windows.
/// @relates socket
error
child_process_inherit
(
socket
x
,
bool
new_value
);
/// Enables or disables nonblocking I/O on `x`.
/// @relates socket
error
nonblocking
(
socket
x
,
bool
new_value
);
/// Convenience functions for checking the result of `recv` or `send`.
/// @relates socket
bool
is_error
(
std
::
make_signed
<
size_t
>::
type
res
,
bool
is_nonblock
);
}
// namespace net
}
// namespace caf
libcaf_net/caf/net/socket_id.hpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#pragma once
#include <cstddef>
#include <limits>
#include "caf/config.hpp"
namespace
caf
{
namespace
net
{
#ifdef CAF_WINDOWS
/// Platform-specific representation of a socket.
/// @relates socket
using
socket_id
=
size_t
;
/// Identifies the invalid socket.
constexpr
socket_id
invalid_socket_id
=
std
::
numeric_limits
<
socket_id
>::
max
();
#else // CAF_WINDOWS
/// Platform-specific representation of a socket.
/// @relates socket
using
socket_id
=
int
;
/// Identifies the invalid socket.
constexpr
socket_id
invalid_socket_id
=
-
1
;
#endif // CAF_WINDOWS
}
// namespace net
}
// namespace caf
libcaf_net/src/socket.cpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#include "caf/net/socket.hpp"
#include "caf/config.hpp"
#include "caf/detail/net_syscall.hpp"
#include "caf/detail/socket_sys_includes.hpp"
#include "caf/logger.hpp"
namespace
caf
{
namespace
net
{
#ifdef CAF_WINDOWS
void
close
(
socket
fd
)
{
closesocket
(
fd
.
id
);
}
int
last_socket_error
()
{
return
WSAGetLastError
();
}
std
::
string
socket_error_as_string
(
int
errcode
)
{
LPTSTR
errorText
=
NULL
;
FormatMessage
(
FORMAT_MESSAGE_FROM_SYSTEM
|
FORMAT_MESSAGE_ALLOCATE_BUFFER
|
FORMAT_MESSAGE_IGNORE_INSERTS
,
nullptr
,
errcode
,
MAKELANGID
(
LANG_NEUTRAL
,
SUBLANG_DEFAULT
),
(
LPTSTR
)
&
errorText
,
0
,
nullptr
);
std
::
string
result
;
if
(
errorText
!=
nullptr
)
{
result
=
errorText
;
// Release memory allocated by FormatMessage().
LocalFree
(
errorText
);
}
return
result
;
}
std
::
string
last_socket_error_as_string
()
{
return
socket_error_as_string
(
last_socket_error
());
}
bool
would_block_or_temporarily_unavailable
(
int
errcode
)
{
return
errcode
==
WSAEWOULDBLOCK
||
errcode
==
WSATRY_AGAIN
;
}
error
child_process_inherit
(
socket
x
,
bool
)
{
// TODO: possible to implement via SetHandleInformation?
if
(
x
==
invalid_socket
)
return
make_error
(
sec
::
network_syscall_failed
,
"ioctlsocket"
,
"invalid socket"
);
return
none
;
}
error
nonblocking
(
socket
x
,
bool
new_value
)
{
u_long
mode
=
new_value
?
1
:
0
;
CAF_NET_SYSCALL
(
"ioctlsocket"
,
res
,
!=
,
0
,
ioctlsocket
(
x
.
id
,
FIONBIO
,
&
mode
));
return
none
;
}
#else // CAF_WINDOWS
void
close
(
socket
fd
)
{
::
close
(
fd
.
id
);
}
int
last_socket_error
()
{
return
errno
;
}
std
::
string
socket_error_as_string
(
int
error_code
)
{
return
strerror
(
error_code
);
}
std
::
string
last_socket_error_as_string
()
{
return
strerror
(
errno
);
}
bool
would_block_or_temporarily_unavailable
(
int
errcode
)
{
return
errcode
==
EAGAIN
||
errcode
==
EWOULDBLOCK
;
}
error
child_process_inherit
(
socket
x
,
bool
new_value
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
x
)
<<
CAF_ARG
(
new_value
));
// read flags for x
CAF_NET_SYSCALL
(
"fcntl"
,
rf
,
==
,
-
1
,
fcntl
(
x
.
id
,
F_GETFD
));
// calculate and set new flags
auto
wf
=
!
new_value
?
rf
|
FD_CLOEXEC
:
rf
&
~
(
FD_CLOEXEC
);
CAF_NET_SYSCALL
(
"fcntl"
,
set_res
,
==
,
-
1
,
fcntl
(
x
.
id
,
F_SETFD
,
wf
));
return
none
;
}
error
nonblocking
(
socket
x
,
bool
new_value
)
{
CAF_LOG_TRACE
(
CAF_ARG
(
x
)
<<
CAF_ARG
(
new_value
));
// read flags for x
CAF_NET_SYSCALL
(
"fcntl"
,
rf
,
==
,
-
1
,
fcntl
(
x
.
id
,
F_GETFL
,
0
));
// calculate and set new flags
auto
wf
=
new_value
?
(
rf
|
O_NONBLOCK
)
:
(
rf
&
(
~
(
O_NONBLOCK
)));
CAF_NET_SYSCALL
(
"fcntl"
,
set_res
,
==
,
-
1
,
fcntl
(
x
.
id
,
F_SETFL
,
wf
));
return
none
;
}
#endif // CAF_WINDOWS
bool
is_error
(
std
::
make_signed
<
size_t
>::
type
res
,
bool
is_nonblock
)
{
if
(
res
<
0
)
{
auto
err
=
last_socket_error
();
return
!
is_nonblock
||
!
would_block_or_temporarily_unavailable
(
err
);
}
return
false
;
}
}
// namespace net
}
// namespace caf
libcaf_net/test/socket.cpp
0 → 100644
View file @
8c1724a8
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE socket
#include "caf/net/socket.hpp"
#include "caf/test/dsl.hpp"
using
namespace
caf
;
using
namespace
caf
::
net
;
CAF_TEST
(
invalid
socket
)
{
auto
x
=
invalid_socket
;
CAF_CHECK_EQUAL
(
x
.
id
,
invalid_socket_id
);
CAF_CHECK_EQUAL
(
child_process_inherit
(
x
,
true
),
sec
::
network_syscall_failed
);
CAF_CHECK_EQUAL
(
nonblocking
(
x
,
true
),
sec
::
network_syscall_failed
);
}
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