Commit 193319d7 authored by Dominik Charousset's avatar Dominik Charousset

Merge pull request #328 from actor-framework/topic/visual_studio

Fix build on MSVC
parents 196ae5f6 36077a3c
......@@ -196,6 +196,9 @@ if(MINGW)
else()
set(EXTRA_FLAGS "${EXTRA_FLAGS} -fPIC")
endif()
if (WIN32)
set(LD_FLAGS ${LD_FLAGS} ws2_32 iphlpapi)
endif()
# iOS support
if(CAF_OSX_SYSROOT)
set(CMAKE_OSX_SYSROOT "${CAF_OSX_SYSROOT}")
......
......@@ -7,6 +7,8 @@
* - ./build/bin/broker -c localhost 4242 *
\ ******************************************************************************/
#include "caf/config.hpp"
#ifdef WIN32
# define _WIN32_WINNT 0x0600
# include <Winsock2.h>
......
......@@ -129,13 +129,15 @@ private:
using std::swap;
swap(host_, nhost);
swap(port_, nport);
auto send_mm = [=] {
unbecome();
send(mm, get_atom::value, host_, port_);
};
// await pending ok/error message first, then send new request to MM
become(
keep_behavior,
(on<ok_atom, actor_addr>() || on<error_atom, string>()) >> [=] {
unbecome();
send(mm, get_atom::value, host_, port_);
}
[=](ok_atom&, actor_addr&) { send_mm(); },
[=](error_atom&, string&) { send_mm(); }
);
},
// simply ignore all requests until we have a connection
......@@ -171,10 +173,10 @@ optional<int> toint(const string& str) {
// converts "+" to the atom '+' and "-" to the atom '-'
optional<atom_value> plus_or_minus(const string& str) {
if (str == "+") {
return {plus_atom::value};
return optional<atom_value>{plus_atom::value};
}
if (str == "-") {
return {minus_atom::value};
return optional<atom_value>{minus_atom::value};
}
return none;
}
......@@ -195,15 +197,18 @@ void client_repl(string host, uint16_t port) {
// defining the handler outside the loop is more efficient as it avoids
// re-creating the same object over and over again
message_handler eval{
on("quit") >> [&] {
[&](const string& cmd) {
if (cmd != "quit")
return;
anon_send_exit(client, exit_reason::user_shutdown);
done = true;
},
on("connect", arg_match) >> [&](string& nhost, string& sport) {
[&](string& arg0, string& arg1, string& arg2) {
if (arg0 == "connect") {
try {
auto lport = std::stoul(sport);
auto lport = std::stoul(arg2);
if (lport < std::numeric_limits<uint16_t>::max()) {
anon_send(client, rebind_atom::value, move(nhost),
anon_send(client, rebind_atom::value, move(arg1),
static_cast<uint16_t>(lport));
}
else {
......@@ -211,12 +216,17 @@ void client_repl(string host, uint16_t port) {
}
}
catch (std::exception&) {
cout << "\"" << sport << "\" is not an unsigned integer"
cout << "\"" << arg2 << "\" is not an unsigned integer"
<< endl;
}
},
on(toint, plus_or_minus, toint) >> [&](int x, atom_value op, int y) {
anon_send(client, op, x, y);
}
else {
auto x = toint(arg0);
auto op = plus_or_minus(arg1);
auto y = toint(arg2);
if (x && y && op)
anon_send(client, *op, *x, *y);
}
},
others >> usage
};
......
......@@ -113,21 +113,19 @@ int main(int argc, char** argv) {
}
}
cout << "*** starting client, type '/help' for a list of commands" << endl;
auto starts_with = [](const string& str) -> function<optional<string> (const string&)> {
return [=](const string& arg) -> optional<string> {
if (arg.compare(0, str.size(), str) == 0) {
return arg;
}
return none;
};
};
istream_iterator<line> eof;
vector<string> words;
for (istream_iterator<line> i(cin); i != eof; ++i) {
auto send_input = [&] {
if (!i->str.empty()) {
anon_send(client_actor, broadcast_atom::value, i->str);
}
};
words.clear();
split(words, i->str, is_any_of(" "));
message_builder(words.begin(), words.end()).apply({
on("/join", arg_match) >> [&](const string& mod, const string& id) {
[&](const string& cmd, const string& mod, const string& id) {
if (cmd == "/join") {
try {
group grp = (mod == "remote") ? io::remote_group(id)
: group::get(mod, id);
......@@ -136,22 +134,26 @@ int main(int argc, char** argv) {
catch (exception& e) {
cerr << "*** exception: " << to_verbose_string(e) << endl;
}
}
else {
send_input();
}
},
on("/quit") >> [&] {
// close STDIN; causes this match loop to quit
[&](const string& cmd) {
if (cmd == "/quit") {
cin.setstate(ios_base::eofbit);
},
on(starts_with("/"), any_vals) >> [&] {
}
else if (cmd[0] == '/') {
cout << "*** available commands:\n"
" /join <module> <group> join a new chat channel\n"
" /quit quit the program\n"
" /help print this text\n" << flush;
},
others >> [&] {
if (! i->str.empty()) {
anon_send(client_actor, broadcast_atom::value, i->str);
}
else {
send_input();
}
},
others >> send_input
});
}
// force actor to quit
......
......@@ -50,14 +50,14 @@ void testee(event_based_actor* self, size_t remaining) {
self->become (
// note: we sent a foo_pair2, but match on foo_pair
// that's safe because both are aliases for std::pair<int, int>
on<foo_pair>() >> [=](const foo_pair& val) {
[=](const foo_pair& val) {
cout << "foo_pair("
<< val.first << ", "
<< val.second << ")"
<< endl;
set_next_behavior();
},
on<foo>() >> [=](const foo& val) {
[=](const foo& val) {
cout << "foo({";
auto i = val.a.begin();
auto end = val.a.end();
......
......@@ -41,7 +41,7 @@ bool operator==(const foo& lhs, const foo& rhs) {
void testee(event_based_actor* self) {
self->become (
on<foo>() >> [=](const foo& val) {
[=](const foo& val) {
aout(self) << "foo("
<< val.a() << ", "
<< val.b() << ")"
......
......@@ -48,7 +48,7 @@ using foo_setter = void (foo::*)(int);
void testee(event_based_actor* self) {
self->become (
on<foo>() >> [=](const foo& val) {
[=](const foo& val) {
aout(self) << "foo("
<< val.a() << ", "
<< val.b() << ")"
......
......@@ -85,7 +85,7 @@ void testee(event_based_actor* self, size_t remaining) {
else self->quit();
};
self->become (
on<bar>() >> [=](const bar& val) {
[=](const bar& val) {
aout(self) << "bar(foo("
<< val.f.a() << ", "
<< val.f.b() << "), "
......@@ -93,7 +93,7 @@ void testee(event_based_actor* self, size_t remaining) {
<< endl;
set_next_behavior();
},
on<baz>() >> [=](const baz& val) {
[=](const baz& val) {
// prints: baz ( foo ( 1, 2 ), bar ( foo ( 3, 4 ), 5 ) )
aout(self) << to_string(make_message(val)) << endl;
set_next_behavior();
......
......@@ -20,6 +20,8 @@
#ifndef CAF_DETAIL_SINGLE_READER_QUEUE_HPP
#define CAF_DETAIL_SINGLE_READER_QUEUE_HPP
#include "caf/config.hpp"
#include <list>
#include <deque>
#include <mutex>
......@@ -28,8 +30,6 @@
#include <limits>
#include <condition_variable> // std::cv_status
#include "caf/config.hpp"
#include "caf/detail/intrusive_partitioned_list.hpp"
namespace caf {
......
......@@ -20,6 +20,8 @@
#ifndef CAF_SCHEDULER_COORDINATOR_HPP
#define CAF_SCHEDULER_COORDINATOR_HPP
#include "caf/config.hpp"
#include <thread>
#include <limits>
#include <memory>
......
......@@ -20,6 +20,8 @@
#ifndef CAF_SET_SCHEDULER_HPP
#define CAF_SET_SCHEDULER_HPP
#include "caf/config.hpp"
#include <thread>
#include <limits>
......
......@@ -39,16 +39,17 @@ namespace detail {
namespace {
pthread_key_t s_key;
pthread_once_t s_key_once = PTHREAD_ONCE_INIT;
using cache_map = std::map<const std::type_info*, std::unique_ptr<memory_cache>>;
} // namespace <anonymous>
memory_cache::~memory_cache() {
// nop
}
#ifdef CAF_CLANG
namespace {
pthread_key_t s_key;
pthread_once_t s_key_once = PTHREAD_ONCE_INIT;
using cache_map = std::map<const std::type_info*,std::unique_ptr<memory_cache>>;
} // namespace <anonymous>
void cache_map_destructor(void* ptr) {
delete reinterpret_cast<cache_map*>(ptr);
......@@ -71,6 +72,30 @@ cache_map& get_cache_map() {
return *cache;
}
#else // !CAF_CLANG
namespace {
thread_local std::unique_ptr<cache_map> s_key;
}
cache_map& get_cache_map() {
if (! s_key) {
s_key = std::unique_ptr<cache_map>(new cache_map);
// insert default types
std::unique_ptr<memory_cache> tmp(new basic_memory_cache<mailbox_element>);
s_key->emplace(&typeid(mailbox_element), move(tmp));
}
return *s_key;
}
#endif
memory_cache::~memory_cache() {
// nop
}
memory_cache* memory::get_cache_map_entry(const std::type_info* tinf) {
auto& cache = get_cache_map();
auto i = cache.find(tinf);
......
......@@ -235,7 +235,7 @@ uint16_t port_of_fd(native_socket fd);
ccall(cc_zero, "listen() failed", listen, listener, 1);
// create read-only end of the pipe
DWORD flags = 0;
auto read_fd = ccall(cc_valid_socket, "WSASocket() failed", WSASocket,
auto read_fd = ccall(cc_valid_socket, "WSASocketW() failed", WSASocketW,
AF_INET, SOCK_STREAM, 0, nullptr, 0, flags);
ccall(cc_zero, "connect() failed", connect, read_fd,
&a.addr, int{sizeof(a.inaddr)});
......@@ -915,10 +915,10 @@ bool write_some(size_t& result, native_socket fd, const void* buf, size_t len) {
bool try_accept(native_socket& result, native_socket fd) {
CAF_LOGF_TRACE(CAF_ARG(fd));
sockaddr addr;
sockaddr_storage addr;
memset(&addr, 0, sizeof(addr));
socklen_t addrlen = sizeof(addr);
result = ::accept(fd, &addr, &addrlen);
result = ::accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
CAF_LOGF_DEBUG("tried to accept a new connection from from socket "
<< fd << ", accept returned " << result);
if (result == invalid_native_socket) {
......
......@@ -33,8 +33,6 @@
# include <winsock2.h>
# include <ws2tcpip.h>
# include <iphlpapi.h>
# pragma comment(lib, "ws2_32.lib")
# pragma comment(lib, "iphlpapi.lib")
#else
# include <sys/socket.h>
# include <netinet/in.h>
......@@ -134,7 +132,7 @@ void for_each_device(bool include_localhost, F fun) {
nullptr, retval,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &msgbuf, 0, nullptr)) {
printf("Error: %s", msgbuf);
printf("Error: %s", static_cast<char*>(msgbuf));
LocalFree(msgbuf);
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment