Skip to content

Commit

Permalink
Merge f00ca0b into 7d9f1c3
Browse files Browse the repository at this point in the history
  • Loading branch information
denizzzka committed Oct 13, 2022
2 parents 7d9f1c3 + f00ca0b commit c37d106
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 7 deletions.
2 changes: 1 addition & 1 deletion dub.sdl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ license "MIT"
copyright "Copyright © 2016"
targetType "sourceLibrary"

dependency "dpq2" version="~>1.1.1"
dependency "dpq2" version="~>1.1.2-winimpr.2"
dependency "vibe-core" version=">=1.9.3 <2.0.0-0"

configuration "release_app" {
Expand Down
19 changes: 13 additions & 6 deletions source/vibe/db/postgresql/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ class Dpq2Connection : dpq2.Connection

if(resetPoll() != PGRES_POLLING_OK)
{
socketEvent().wait(socketTimeout);
this.socketEvent().wait(socketTimeout);
continue;
}

Expand All @@ -159,20 +159,27 @@ class Dpq2Connection : dpq2.Connection
settings.afterStartConnectOrReset(this);
}

version(Posix)
private auto socketEvent()
{
import vibe.core.core;
import core.sys.posix.fcntl;

version(Posix)
{
import core.sys.posix.fcntl;
assert((fcntl(this.posixSocket, F_GETFL, 0) & O_NONBLOCK), "Socket assumed to be non-blocking already");
}
assert((fcntl(this.posixSocket, F_GETFL, 0) & O_NONBLOCK), "Socket assumed to be non-blocking already");

// vibe-core right now supports only read trigger event
// it also closes the socket on scope exit, thus a socket duplication here
return createFileDescriptorEvent(this.posixSocketDuplicate, FileDescriptorEvent.Trigger.read);
}
else version(Windows)
{
private auto socketEvent()
{
import vibe.db.postgresql.windows: createFileDescriptorEvent;

return createFileDescriptorEvent(this.posixSocketDuplicate);
}
}

private void waitEndOfReadAndConsume(in Duration timeout)
{
Expand Down
98 changes: 98 additions & 0 deletions source/vibe/db/postgresql/windows.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
module vibe.db.postgresql.windows;

version(Windows):

import core.time: Duration;
import core.sys.windows.winsock2;
import std.exception: enforce;
import std.conv: to;
import std.socket: SOCKET;
import dpq2.connection: ConnectionException;

package SocketEvent createFileDescriptorEvent(SOCKET _socket)
{
//FIXME: SOCKET sizeof mismatch. need to remove cast. Details: https://github.com/etcimon/windows-headers/issues/12
auto socket = cast(int) _socket;

WSAEVENT ev = WSACreateEvent();

if(ev == WSA_INVALID_EVENT)
throw new ConnectionException("WSACreateEvent error, code "~WSAGetLastError().to!string);

auto r = WSAEventSelect(socket, ev, FD_READ);

if(r)
throw new ConnectionException("WSAEventSelect error, code "~WSAGetLastError().to!string);

return SocketEvent(ev);
}

struct SocketEvent
{
private WSAEVENT event;
//TODO: deregister events if struct destroyed?

void wait()
{
if(!waitImpl(WSA_INFINITE))
throw new ConnectionException("WSA_WAIT_TIMEOUT during WSA_INFINITE awaiting");
}

bool wait(Duration timeout)
{
return waitImpl(timeout.total!"msecs".to!int);
}

private bool waitImpl(DWORD timeout)
{
auto idx = WSAWaitForMultipleEvents(1, &event, false, timeout, false);

if(idx == WSA_WAIT_FAILED)
throw new ConnectionException("WSAWaitForMultipleEvents error, code "~WSAGetLastError().to!string);

if(WSAResetEvent(event) == false)
throw new ConnectionException("WSAResetEvent error, code "~WSAGetLastError().to!string);

if(idx == WSA_WAIT_TIMEOUT)
return false;

return true;
}
}

private:

alias WSAEVENT = void*;

// Not documented on MSDN
enum {
FD_READ_BIT,
FD_WRITE_BIT,
FD_OOB_BIT,
FD_ACCEPT_BIT,
FD_CONNECT_BIT,
FD_CLOSE_BIT,
FD_QOS_BIT,
FD_GROUP_QOS_BIT,
FD_ROUTING_INTERFACE_CHANGE_BIT,
FD_ADDRESS_LIST_CHANGE_BIT,
FD_MAX_EVENTS // = 10
}

import core.sys.windows.winbase;

const WSA_INFINITE = INFINITE;
const WSA_INVALID_EVENT = WSAEVENT.init;
const WSA_WAIT_FAILED = cast(DWORD)-1;
const WSA_WAIT_TIMEOUT = WAIT_TIMEOUT;
const int FD_READ = 1 << FD_READ_BIT;

extern(Windows) nothrow @nogc
{
import core.sys.windows.windef;

WSAEVENT WSACreateEvent();
int WSAEventSelect(SOCKET, WSAEVENT, int);
BOOL WSAResetEvent(WSAEVENT);
DWORD WSAWaitForMultipleEvents(DWORD, const(WSAEVENT)*, BOOL, DWORD, BOOL);
}

0 comments on commit c37d106

Please sign in to comment.