Replace std min/max. Fix #35

This commit is contained in:
Eugen Wissner 2018-04-26 10:23:06 +02:00
parent 3468d6ea00
commit c0f9e5be10
8 changed files with 206 additions and 202 deletions

View File

@ -1,187 +1,187 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/** /**
* Event loop implementation for Linux. * Event loop implementation for Linux.
* *
* Copyright: Eugene Wissner 2016-2018. * Copyright: Eugene Wissner 2016-2018.
* License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/, * License: $(LINK2 https://www.mozilla.org/en-US/MPL/2.0/,
* Mozilla Public License, v. 2.0). * Mozilla Public License, v. 2.0).
* Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner) * Authors: $(LINK2 mailto:info@caraus.de, Eugene Wissner)
* Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/async/event/epoll.d, * Source: $(LINK2 https://github.com/caraus-ecms/tanya/blob/master/source/tanya/async/event/epoll.d,
* tanya/async/event/epoll.d) * tanya/async/event/epoll.d)
*/ */
module tanya.async.event.epoll; module tanya.async.event.epoll;
version (D_Ddoc) version (D_Ddoc)
{ {
} }
else version (linux): else version (linux):
import core.stdc.errno; import core.stdc.errno;
public import core.sys.linux.epoll; public import core.sys.linux.epoll;
import core.sys.posix.unistd; import core.sys.posix.unistd;
import core.time; import core.time;
import std.algorithm.comparison; import tanya.algorithm.comparison;
import tanya.async.event.selector; import tanya.async.event.selector;
import tanya.async.loop; import tanya.async.loop;
import tanya.async.protocol; import tanya.async.protocol;
import tanya.async.transport; import tanya.async.transport;
import tanya.async.watcher; import tanya.async.watcher;
import tanya.container.array; import tanya.container.array;
import tanya.memory; import tanya.memory;
import tanya.network.socket; import tanya.network.socket;
extern (C) nothrow @nogc extern (C) nothrow @nogc
{ {
int epoll_create1(int flags); int epoll_create1(int flags);
int epoll_ctl (int epfd, int op, int fd, epoll_event *event); int epoll_ctl (int epfd, int op, int fd, epoll_event *event);
int epoll_wait (int epfd, epoll_event *events, int maxevents, int timeout); int epoll_wait (int epfd, epoll_event *events, int maxevents, int timeout);
} }
final class EpollLoop : SelectorLoop final class EpollLoop : SelectorLoop
{ {
protected int fd; protected int fd;
private Array!epoll_event events; private Array!epoll_event events;
/** /**
* Initializes the loop. * Initializes the loop.
*/ */
this() @nogc this() @nogc
{ {
if ((fd = epoll_create1(EPOLL_CLOEXEC)) < 0) if ((fd = epoll_create1(EPOLL_CLOEXEC)) < 0)
{ {
throw defaultAllocator.make!BadLoopException("epoll initialization failed"); throw defaultAllocator.make!BadLoopException("epoll initialization failed");
} }
super(); super();
events = Array!epoll_event(maxEvents); events = Array!epoll_event(maxEvents);
} }
/** /**
* Frees loop internals. * Frees loop internals.
*/ */
~this() @nogc ~this() @nogc
{ {
close(fd); close(fd);
} }
/** /**
* Should be called if the backend configuration changes. * Should be called if the backend configuration changes.
* *
* Params: * Params:
* watcher = Watcher. * watcher = Watcher.
* oldEvents = The events were already set. * oldEvents = The events were already set.
* events = The events should be set. * events = The events should be set.
* *
* Returns: $(D_KEYWORD true) if the operation was successful. * Returns: $(D_KEYWORD true) if the operation was successful.
*/ */
protected override bool reify(SocketWatcher watcher, protected override bool reify(SocketWatcher watcher,
EventMask oldEvents, EventMask oldEvents,
EventMask events) @nogc EventMask events) @nogc
{ {
int op = EPOLL_CTL_DEL; int op = EPOLL_CTL_DEL;
epoll_event ev; epoll_event ev;
if (events == oldEvents) if (events == oldEvents)
{ {
return true; return true;
} }
if (events && oldEvents) if (events && oldEvents)
{ {
op = EPOLL_CTL_MOD; op = EPOLL_CTL_MOD;
} }
else if (events && !oldEvents) else if (events && !oldEvents)
{ {
op = EPOLL_CTL_ADD; op = EPOLL_CTL_ADD;
} }
ev.data.fd = watcher.socket.handle; ev.data.fd = watcher.socket.handle;
ev.events = (events & (Event.read | Event.accept) ? EPOLLIN | EPOLLPRI : 0) ev.events = (events & (Event.read | Event.accept) ? EPOLLIN | EPOLLPRI : 0)
| (events & Event.write ? EPOLLOUT : 0) | (events & Event.write ? EPOLLOUT : 0)
| EPOLLET; | EPOLLET;
return epoll_ctl(fd, op, watcher.socket.handle, &ev) == 0; return epoll_ctl(fd, op, watcher.socket.handle, &ev) == 0;
} }
/** /**
* Does the actual polling. * Does the actual polling.
*/ */
protected override void poll() @nogc protected override void poll() @nogc
{ {
// Don't block // Don't block
immutable timeout = cast(immutable int) blockTime.total!"msecs"; immutable timeout = cast(immutable int) blockTime.total!"msecs";
auto eventCount = epoll_wait(fd, events.get().ptr, maxEvents, timeout); auto eventCount = epoll_wait(fd, events.get().ptr, maxEvents, timeout);
if (eventCount < 0) if (eventCount < 0)
{ {
if (errno != EINTR) if (errno != EINTR)
{ {
throw defaultAllocator.make!BadLoopException(); throw defaultAllocator.make!BadLoopException();
} }
return; return;
} }
for (auto i = 0; i < eventCount; ++i) for (auto i = 0; i < eventCount; ++i)
{ {
auto transport = cast(StreamTransport) connections[events[i].data.fd]; auto transport = cast(StreamTransport) connections[events[i].data.fd];
if (transport is null) if (transport is null)
{ {
auto connection = cast(ConnectionWatcher) connections[events[i].data.fd]; auto connection = cast(ConnectionWatcher) connections[events[i].data.fd];
assert(connection !is null); assert(connection !is null);
acceptConnections(connection); acceptConnections(connection);
} }
else if (events[i].events & EPOLLERR) else if (events[i].events & EPOLLERR)
{ {
kill(transport); kill(transport);
continue; continue;
} }
else if (events[i].events & (EPOLLIN | EPOLLPRI | EPOLLHUP)) else if (events[i].events & (EPOLLIN | EPOLLPRI | EPOLLHUP))
{ {
SocketException exception; SocketException exception;
try try
{ {
ptrdiff_t received; ptrdiff_t received;
do do
{ {
received = transport.socket.receive(transport.output[]); received = transport.socket.receive(transport.output[]);
transport.output += received; transport.output += received;
} }
while (received); while (received);
} }
catch (SocketException e) catch (SocketException e)
{ {
exception = e; exception = e;
} }
if (transport.socket.disconnected) if (transport.socket.disconnected)
{ {
kill(transport, exception); kill(transport, exception);
continue; continue;
} }
else if (transport.output.length) else if (transport.output.length)
{ {
pendings.insertBack(transport); pendings.insertBack(transport);
} }
} }
if (events[i].events & EPOLLOUT) if (events[i].events & EPOLLOUT)
{ {
transport.writeReady = true; transport.writeReady = true;
if (transport.input.length) if (transport.input.length)
{ {
feed(transport); feed(transport);
} }
} }
} }
} }
/** /**
* Returns: The blocking time. * Returns: The blocking time.
*/ */
override protected @property inout(Duration) blockTime() override protected @property inout(Duration) blockTime()
inout @safe pure nothrow inout @safe pure nothrow
{ {
return min(super.blockTime, 1.dur!"seconds"); return min(super.blockTime, 1.dur!"seconds");
} }
} }

View File

@ -52,7 +52,7 @@ import core.stdc.errno;
import core.sys.posix.time; // timespec import core.sys.posix.time; // timespec
import core.sys.posix.unistd; import core.sys.posix.unistd;
import core.time; import core.time;
import std.algorithm.comparison; import tanya.algorithm.comparison;
import tanya.async.event.selector; import tanya.async.event.selector;
import tanya.async.loop; import tanya.async.loop;
import tanya.async.transport; import tanya.async.transport;
@ -217,7 +217,7 @@ final class KqueueLoop : SelectorLoop
timespec ts; timespec ts;
blockTime.split!("seconds", "nsecs")(ts.tv_sec, ts.tv_nsec); blockTime.split!("seconds", "nsecs")(ts.tv_sec, ts.tv_nsec);
if (changeCount > maxEvents) if (changeCount > maxEvents)
{ {
events.length = changes.length; events.length = changes.length;
} }

View File

@ -15,13 +15,14 @@
module tanya.container.array; module tanya.container.array;
import core.checkedint; import core.checkedint;
import std.algorithm.comparison; import std.algorithm.comparison : equal;
import std.algorithm.mutation : bringToFront, import std.algorithm.mutation : bringToFront,
copy, copy,
fill, fill,
initializeAll, initializeAll,
uninitializedFill; uninitializedFill;
import std.meta; import std.meta;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.exception; import tanya.exception;
import tanya.memory; import tanya.memory;

View File

@ -15,8 +15,9 @@
*/ */
module tanya.container.list; module tanya.container.list;
import std.algorithm.comparison; import std.algorithm.comparison : equal;
import std.algorithm.searching; import std.algorithm.searching;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.container.entry; import tanya.container.entry;
import tanya.memory; import tanya.memory;
@ -707,7 +708,7 @@ struct SList(T)
auto outOfScopeList = typeof(this)(allocator); auto outOfScopeList = typeof(this)(allocator);
outOfScopeList.head = *r.head; outOfScopeList.head = *r.head;
*r.head = null; *r.head = null;
return r; return r;
} }

View File

@ -26,9 +26,10 @@
*/ */
module tanya.container.string; module tanya.container.string;
import std.algorithm.comparison; import std.algorithm.comparison : cmp, equal;
import std.algorithm.mutation : bringToFront, copy; import std.algorithm.mutation : bringToFront, copy;
import std.algorithm.searching; import std.algorithm.searching;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.memory; import tanya.memory;
import tanya.meta.trait; import tanya.meta.trait;

View File

@ -14,9 +14,10 @@
*/ */
module tanya.math.mp; module tanya.math.mp;
import std.algorithm.comparison; import std.algorithm.comparison : cmp, equal;
import std.algorithm.mutation : copy, fill, reverse; import std.algorithm.mutation : copy, fill, reverse;
import std.range; import std.range;
import tanya.algorithm.comparison;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.container.array; import tanya.container.array;
import tanya.encoding.ascii; import tanya.encoding.ascii;
@ -1256,7 +1257,7 @@ struct Integer
for (size_t i; i < this.size; ++i) for (size_t i; i < this.size; ++i)
{ {
const limit = min(factor.size, digits - i); const limit = min(cast(size_t) factor.size, digits - i);
word carry; word carry;
auto k = i; auto k = i;

View File

@ -23,7 +23,7 @@
*/ */
module tanya.memory.smartref; module tanya.memory.smartref;
import std.algorithm.comparison; import tanya.algorithm.comparison;
import tanya.algorithm.mutation; import tanya.algorithm.mutation;
import tanya.conv; import tanya.conv;
import tanya.exception; import tanya.exception;
@ -259,7 +259,7 @@ struct RefCounted(T)
* reference types like classes, that can be accessed directly. * reference types like classes, that can be accessed directly.
* *
* Params: * Params:
* op = Operation. * op = Operation.
* *
* Returns: Reference to the pointed value. * Returns: Reference to the pointed value.
*/ */
@ -276,7 +276,7 @@ struct RefCounted(T)
} }
/** /**
* Returns: Whether this $(D_PSYMBOL RefCounted) already has an internal * Returns: Whether this $(D_PSYMBOL RefCounted) already has an internal
* storage. * storage.
*/ */
@property bool isInitialized() const @property bool isInitialized() const
@ -489,7 +489,7 @@ version (unittest)
* A = Types of the arguments to the constructor of $(D_PARAM T). * A = Types of the arguments to the constructor of $(D_PARAM T).
* allocator = Allocator. * allocator = Allocator.
* args = Constructor arguments of $(D_PARAM T). * args = Constructor arguments of $(D_PARAM T).
* *
* Returns: Newly created $(D_PSYMBOL RefCounted!T). * Returns: Newly created $(D_PSYMBOL RefCounted!T).
* *
* Precondition: $(D_INLINECODE allocator !is null) * Precondition: $(D_INLINECODE allocator !is null)
@ -743,7 +743,7 @@ struct Unique(T)
* reference types like classes, that can be accessed directly. * reference types like classes, that can be accessed directly.
* *
* Params: * Params:
* op = Operation. * op = Operation.
* *
* Returns: Reference to the pointed value. * Returns: Reference to the pointed value.
*/ */
@ -837,7 +837,7 @@ struct Unique(T)
* A = Types of the arguments to the constructor of $(D_PARAM T). * A = Types of the arguments to the constructor of $(D_PARAM T).
* allocator = Allocator. * allocator = Allocator.
* args = Constructor arguments of $(D_PARAM T). * args = Constructor arguments of $(D_PARAM T).
* *
* Returns: Newly created $(D_PSYMBOL Unique!T). * Returns: Newly created $(D_PSYMBOL Unique!T).
* *
* Precondition: $(D_INLINECODE allocator !is null) * Precondition: $(D_INLINECODE allocator !is null)

View File

@ -16,10 +16,10 @@ module tanya.network.socket;
import core.stdc.errno; import core.stdc.errno;
import core.time; import core.time;
import std.algorithm.comparison;
public import std.socket : SocketOption, SocketOptionLevel; public import std.socket : SocketOption, SocketOptionLevel;
import std.traits; import std.traits;
import std.typecons; import std.typecons;
import tanya.algorithm.comparison;
import tanya.memory; import tanya.memory;
import tanya.os.error; import tanya.os.error;