mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-07 02:58:38 +00:00
netty: non-blocking server test
This commit is contained in:
parent
b3819f30dc
commit
a65a4c8621
@ -42,32 +42,7 @@ append config {
|
|||||||
<provides> <service name="Nic"/> </provides>
|
<provides> <service name="Nic"/> </provides>
|
||||||
</start>
|
</start>
|
||||||
|
|
||||||
<start name="socket_fs">}
|
<start name="socket_fs">
|
||||||
|
|
||||||
if { false } { append config {
|
|
||||||
<binary name="ram_fs"/>
|
|
||||||
<resource name="RAM" quantum="10M"/>
|
|
||||||
<provides> <service name="File_system"/> </provides>
|
|
||||||
<config>
|
|
||||||
<content>
|
|
||||||
<inline name="new_socket">33</inline>
|
|
||||||
<dir name="33">
|
|
||||||
<inline name="bind"></inline>
|
|
||||||
<inline name="listen"></inline>
|
|
||||||
<inline name="accept">44</inline>
|
|
||||||
<inline name="local">10.0.2.55:8888</inline>
|
|
||||||
<!-- not connected <inline name="remote"></inline> -->
|
|
||||||
<!-- not connected <inline name="data"></inline> -->
|
|
||||||
</dir>
|
|
||||||
<dir name="44">
|
|
||||||
<inline name="local">10.0.2.55:8888</inline>
|
|
||||||
<inline name="remote">10.0.2.1:13001</inline>
|
|
||||||
<inline name="data">REQUEST</inline>
|
|
||||||
</dir>
|
|
||||||
</content>
|
|
||||||
<default-policy root="/" writeable="yes" />
|
|
||||||
</config>}
|
|
||||||
} else { append config {
|
|
||||||
<binary name="vfs"/>
|
<binary name="vfs"/>
|
||||||
<resource name="RAM" quantum="32M"/>
|
<resource name="RAM" quantum="32M"/>
|
||||||
<provides> <service name="File_system"/> </provides>
|
<provides> <service name="File_system"/> </provides>
|
||||||
@ -79,15 +54,13 @@ if { false } { append config {
|
|||||||
</dir>
|
</dir>
|
||||||
</vfs>
|
</vfs>
|
||||||
<default-policy root="/socket" writeable="yes" />
|
<default-policy root="/socket" writeable="yes" />
|
||||||
</config>}
|
</config>
|
||||||
}
|
|
||||||
append config {
|
|
||||||
</start>
|
</start>
|
||||||
|
|
||||||
<start name="netty-server-80">
|
<start name="netty-server-80">
|
||||||
<binary name="test-netty"/>
|
<binary name="test-netty"/>
|
||||||
<resource name="RAM" quantum="4M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<config ld_verbose="yes" port="80" read_write="no">
|
<config ld_verbose="yes" port="80" read_write="no" nonblock="true">
|
||||||
<vfs>
|
<vfs>
|
||||||
<dir name="dev"> <log/> </dir>
|
<dir name="dev"> <log/> </dir>
|
||||||
<dir name="socket"> <fs/> </dir>
|
<dir name="socket"> <fs/> </dir>
|
||||||
@ -100,7 +73,7 @@ append config {
|
|||||||
<start name="netty-server-8080">
|
<start name="netty-server-8080">
|
||||||
<binary name="test-netty"/>
|
<binary name="test-netty"/>
|
||||||
<resource name="RAM" quantum="4M"/>
|
<resource name="RAM" quantum="4M"/>
|
||||||
<config ld_verbose="yes" mode="server" port="8080">
|
<config ld_verbose="yes" mode="server" port="8080" nonblock="false">
|
||||||
<vfs>
|
<vfs>
|
||||||
<dir name="dev"> <log/> </dir>
|
<dir name="dev"> <log/> </dir>
|
||||||
<dir name="socket"> <fs/> </dir>
|
<dir name="socket"> <fs/> </dir>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* \brief Network echo test
|
* \brief Network TCP echo test
|
||||||
* \author Christian Helmuth
|
* \author Christian Helmuth
|
||||||
* \date 2015-09-21
|
* \date 2015-09-21
|
||||||
*/
|
*/
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
@ -56,121 +57,63 @@ static void print(Genode::Output &output, sockaddr_in const &addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum Test_mode { TEST_READER_WRITER, TEST_TRADITIONAL };
|
static size_t test_nonblocking(int cd, bool const use_read_write)
|
||||||
|
|
||||||
static Test_mode const test_mode = TEST_TRADITIONAL;
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************
|
|
||||||
** Multi-threaded reader-writer test **
|
|
||||||
***************************************/
|
|
||||||
|
|
||||||
class Worker : public Genode::Thread_deprecated<0x4000>
|
|
||||||
{
|
{
|
||||||
protected:
|
Genode::log("test in non-blocking mode");
|
||||||
|
|
||||||
Timer::Connection _timer;
|
int ret = 0;
|
||||||
|
|
||||||
char _name[128];
|
|
||||||
unsigned _id;
|
|
||||||
int _sd;
|
|
||||||
char _buf[4096];
|
|
||||||
|
|
||||||
char const *_init_name(char const *type, unsigned id)
|
|
||||||
{
|
|
||||||
snprintf(_name, sizeof(_name), "%s.%u", type, id);
|
|
||||||
return _name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Worker(Genode::Env &env, char const *type, unsigned id, int sd)
|
|
||||||
:
|
|
||||||
Genode::Thread_deprecated<0x4000>(_init_name(type, id)),
|
|
||||||
_timer(env), _id(id), _sd(sd)
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct Reader : Worker
|
|
||||||
{
|
|
||||||
Reader(Genode::Env &env, unsigned id, int sd)
|
|
||||||
: Worker(env, "reader", id, sd) { }
|
|
||||||
|
|
||||||
void entry() override
|
|
||||||
{
|
{
|
||||||
while (true) {
|
ret = fcntl(cd, F_GETFL);
|
||||||
// _timer.msleep(100);
|
if (ret == -1) DIE("fcntl");
|
||||||
|
Genode::log("F_GETFL returned ", Genode::Hex(ret), "(O_NONBLOCK=", !!(ret & O_NONBLOCK), ")");
|
||||||
|
|
||||||
int const ret = ::read(_sd, _buf, sizeof(_buf));
|
ret = fcntl(cd, F_SETFL, ret | O_NONBLOCK);
|
||||||
|
if (ret == -1) DIE("fcntl");
|
||||||
|
|
||||||
if (ret == -1)
|
ret = fcntl(cd, F_GETFL);
|
||||||
break;
|
if (ret == -1) DIE("fcntl");
|
||||||
}
|
Genode::log("F_GETFL returned ", Genode::Hex(ret), "(O_NONBLOCK=", !!(ret & O_NONBLOCK), ")");
|
||||||
|
|
||||||
Genode::log(Genode::Cstring(_name), " finished errno=", errno);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
|
static char data[64*1024];
|
||||||
|
|
||||||
struct Writer : Worker
|
while (true) {
|
||||||
{
|
ret = use_read_write
|
||||||
Writer(Genode::Env &env, unsigned id, int sd)
|
? read(cd, data, sizeof(data))
|
||||||
: Worker(env, "writer", id, sd) { }
|
: recv(cd, data, sizeof(data), 0);
|
||||||
|
|
||||||
void entry() override
|
if (ret == 0) {
|
||||||
{
|
Genode::log("experienced EOF");
|
||||||
size_t size = 0;
|
return count;
|
||||||
|
|
||||||
if (0) {
|
|
||||||
size = sizeof(_buf);
|
|
||||||
memset(_buf, 'x', size - 1);
|
|
||||||
} else {
|
|
||||||
size = strlen(_name) + 1;
|
|
||||||
strcpy(_buf, _name);
|
|
||||||
}
|
|
||||||
_buf[size - 1] = '\n';
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
// _timer.msleep(10 + _id*5);
|
|
||||||
|
|
||||||
int const ret = ::write(_sd, _buf, size);
|
|
||||||
|
|
||||||
if (ret == -1)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Genode::log(Genode::Cstring(_name), " finished errno=", errno);
|
if (ret > 0) {
|
||||||
|
/* echo received data */
|
||||||
|
ret = use_read_write
|
||||||
|
? write(cd, data, ret)
|
||||||
|
: send(cd, data, ret, 0);
|
||||||
|
if (ret == -1) DIE(use_read_write ? "write" : "send");
|
||||||
|
|
||||||
|
count += ret;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errno != EAGAIN) DIE(use_read_write ? "read" : "recv");
|
||||||
|
|
||||||
|
Genode::log("block in select because of EAGAIN");
|
||||||
|
fd_set read_fds; FD_ZERO(&read_fds); FD_SET(cd, &read_fds);
|
||||||
|
int ret = select(cd + 1, &read_fds, nullptr, nullptr, nullptr);
|
||||||
|
if (ret == -1) DIE("select");
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static void test_reader_writer(Genode::Env &env, int cd)
|
|
||||||
{
|
|
||||||
static Reader r0(env, 0, cd);
|
|
||||||
static Reader r1(env, 1, cd);
|
|
||||||
static Reader r2(env, 2, cd);
|
|
||||||
static Writer w0(env, 0, cd);
|
|
||||||
static Writer w1(env, 1, cd);
|
|
||||||
static Writer w2(env, 2, cd);
|
|
||||||
|
|
||||||
r0.start();
|
|
||||||
r1.start();
|
|
||||||
r2.start();
|
|
||||||
w0.start();
|
|
||||||
w1.start();
|
|
||||||
w2.start();
|
|
||||||
|
|
||||||
Genode::sleep_forever();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************
|
static size_t test_blocking(int cd, bool const use_read_write)
|
||||||
** Traditional (blocking) socket test **
|
|
||||||
****************************************/
|
|
||||||
|
|
||||||
static size_t test_traditional(int cd, bool const use_read_write)
|
|
||||||
{
|
{
|
||||||
|
Genode::log("test in blocking mode");
|
||||||
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
static char data[64*1024];
|
static char data[64*1024];
|
||||||
@ -185,7 +128,10 @@ static size_t test_traditional(int cd, bool const use_read_write)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
if (ret == 0) return count;
|
if (ret == 0) {
|
||||||
|
Genode::log("experienced EOF");
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_read_write) {
|
if (use_read_write) {
|
||||||
ret = write(cd, data, ret);
|
ret = write(cd, data, ret);
|
||||||
@ -238,6 +184,10 @@ static void server(Genode::Env &env, Genode::Xml_node const config)
|
|||||||
|
|
||||||
unsigned const port = config.attribute_value("port", 8080U);
|
unsigned const port = config.attribute_value("port", 8080U);
|
||||||
bool const use_read_write = config.attribute_value("read_write", false);
|
bool const use_read_write = config.attribute_value("read_write", false);
|
||||||
|
bool const nonblock = config.attribute_value("nonblock", false);
|
||||||
|
|
||||||
|
Genode::log("config: port=", port, " read_write=", use_read_write,
|
||||||
|
" nonblock=", nonblock);
|
||||||
|
|
||||||
sockaddr_in const addr { 0, AF_INET, htons(port), { INADDR_ANY } };
|
sockaddr_in const addr { 0, AF_INET, htons(port), { INADDR_ANY } };
|
||||||
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
|
sockaddr const *paddr = reinterpret_cast<sockaddr const *>(&addr);
|
||||||
@ -266,12 +216,10 @@ static void server(Genode::Env &env, Genode::Xml_node const config)
|
|||||||
|
|
||||||
test_getnames(cd);
|
test_getnames(cd);
|
||||||
|
|
||||||
if (0) {
|
size_t const count = nonblock
|
||||||
test_reader_writer(env, cd);
|
? test_nonblocking(cd, use_read_write)
|
||||||
} else {
|
: test_blocking(cd, use_read_write);
|
||||||
size_t const count = test_traditional(cd, use_read_write);
|
Genode::log("echoed ", count, " bytes");
|
||||||
Genode::log("echoed ", count, " bytes");
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = shutdown(cd, SHUT_RDWR);
|
ret = shutdown(cd, SHUT_RDWR);
|
||||||
if (ret == -1) DIE("shutdown");
|
if (ret == -1) DIE("shutdown");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user