// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "runtime.h"
#include "defs_GOOS_GOARCH.h"
#include "os_GOOS.h"

#define DWORD_MAX 0xffffffff

#pragma dynimport runtime·CreateIoCompletionPort CreateIoCompletionPort "kernel32.dll"
#pragma dynimport runtime·GetQueuedCompletionStatus GetQueuedCompletionStatus "kernel32.dll"
#pragma dynimport runtime·WSAGetOverlappedResult WSAGetOverlappedResult "ws2_32.dll"

extern void *runtime·CreateIoCompletionPort;
extern void *runtime·GetQueuedCompletionStatus;
extern void *runtime·WSAGetOverlappedResult;

#define INVALID_HANDLE_VALUE ((uintptr)-1)

// net_op must be the same as beginning of net.operation. Keep these in sync.
typedef struct net_op net_op;
struct net_op
{
	// used by windows
	Overlapped	o;
	// used by netpoll
	PollDesc*	pd;
	int32	mode;
	int32	errno;
	uint32	qty;
};

typedef struct OverlappedEntry OverlappedEntry;
struct OverlappedEntry
{
	uintptr	key;
	net_op*	op;  // In reality it's Overlapped*, but we cast it to net_op* anyway.
	uintptr	internal;
	uint32	qty;
};

static void handlecompletion(G **gpp, net_op *o, int32 errno, uint32 qty);

static uintptr iocphandle = INVALID_HANDLE_VALUE;  // completion port io handle

void
runtime·netpollinit(void)
{
	iocphandle = (uintptr)runtime·stdcall(runtime·CreateIoCompletionPort, 4, INVALID_HANDLE_VALUE, (uintptr)0, (uintptr)0, (uintptr)DWORD_MAX);
	if(iocphandle == 0) {
		runtime·printf("netpoll: failed to create iocp handle (errno=%d)\n", runtime·getlasterror());
		runtime·throw("netpoll: failed to create iocp handle");
	}
	return;
}

int32
runtime·netpollopen(uintptr fd, PollDesc *pd)
{
	USED(pd);
	if(runtime·stdcall(runtime·CreateIoCompletionPort, 4, fd, iocphandle, (uintptr)0, (uintptr)0) == 0)
		return -runtime·getlasterror();
	return 0;
}

int32
runtime·netpollclose(uintptr fd)
{
	// nothing to do
	USED(fd);
	return 0;
}

// Polls for completed network IO.
// Returns list of goroutines that become runnable.
G*
runtime·netpoll(bool block)
{
	OverlappedEntry entries[64];
	uint32 wait, qty, key, flags, n, i;
	int32 errno;
	net_op *op;
	G *gp;

	if(iocphandle == INVALID_HANDLE_VALUE)
		return nil;
	gp = nil;
	wait = 0;
	if(block)
		wait = INFINITE;
retry:
	if(runtime·GetQueuedCompletionStatusEx != nil) {
		n = nelem(entries) / runtime·gomaxprocs;
		if(n < 8)
			n = 8;
		if(runtime·stdcall(runtime·GetQueuedCompletionStatusEx, 6, iocphandle, entries, (uintptr)n, &n, (uintptr)wait, (uintptr)0) == 0) {
			errno = runtime·getlasterror();
			if(!block && errno == WAIT_TIMEOUT)
				return nil;
			runtime·printf("netpoll: GetQueuedCompletionStatusEx failed (errno=%d)\n", errno);
			runtime·throw("netpoll: GetQueuedCompletionStatusEx failed");
		}
		for(i = 0; i < n; i++) {
			op = entries[i].op;
			errno = 0;
			qty = 0;
			if(runtime·stdcall(runtime·WSAGetOverlappedResult, 5, runtime·netpollfd(op->pd), op, &qty, (uintptr)0, (uintptr)&flags) == 0)
				errno = runtime·getlasterror();
			handlecompletion(&gp, op, errno, qty);
		}
	} else {
		op = nil;
		errno = 0;
		qty = 0;
		if(runtime·stdcall(runtime·GetQueuedCompletionStatus, 5, iocphandle, &qty, &key, &op, (uintptr)wait) == 0) {
			errno = runtime·getlasterror();
			if(!block && errno == WAIT_TIMEOUT)
				return nil;
			if(op == nil) {
				runtime·printf("netpoll: GetQueuedCompletionStatus failed (errno=%d)\n", errno);
				runtime·throw("netpoll: GetQueuedCompletionStatus failed");
			}
			// dequeued failed IO packet, so report that
		}
		handlecompletion(&gp, op, errno, qty);
	}
	if(block && gp == nil)
		goto retry;
	return gp;
}

static void
handlecompletion(G **gpp, net_op *op, int32 errno, uint32 qty)
{
	int32 mode;

	if(op == nil)
		runtime·throw("netpoll: GetQueuedCompletionStatus returned op == nil");
	mode = op->mode;
	if(mode != 'r' && mode != 'w') {
		runtime·printf("netpoll: GetQueuedCompletionStatus returned invalid mode=%d\n", mode);
		runtime·throw("netpoll: GetQueuedCompletionStatus returned invalid mode");
	}
	op->errno = errno;
	op->qty = qty;
	runtime·netpollready(gpp, op->pd, mode);
}
