Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2013 The Go Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style | |
3 // license that can be found in the LICENSE file. | |
4 | |
5 #include "runtime.h" | |
6 #include "defs_GOOS_GOARCH.h" | |
7 #include "os_GOOS.h" | |
8 | |
9 #pragma dynimport runtime·CreateIoCompletionPort CreateIoCompletionPort "kernel3 2.dll" | |
10 #pragma dynimport runtime·GetQueuedCompletionStatus GetQueuedCompletionStatus "k ernel32.dll" | |
11 | |
12 extern void *runtime·CreateIoCompletionPort; | |
13 extern void *runtime·GetQueuedCompletionStatus; | |
14 | |
15 #define INVALID_HANDLE_VALUE ((uintptr)-1) | |
16 | |
17 #pragma pack on | |
18 | |
19 // net_anOp must be the same as beginning of net.anOp. Keep these in sync. | |
20 typedef struct net_anOp net_anOp; | |
21 struct net_anOp { | |
22 // used by windows | |
23 Overlapped o; | |
24 // my extras | |
25 uintptr runtimeCtx; | |
26 int32 mode; | |
27 int32 errno; | |
28 uint32 qty; | |
29 }; | |
30 | |
31 #pragma pack off | |
32 | |
33 static uintptr cpiohandle = INVALID_HANDLE_VALUE; // completion port io handle | |
34 | |
35 void | |
36 runtime·netpollinit(void) | |
37 { | |
38 cpiohandle = (uintptr)runtime·stdcall(runtime·CreateIoCompletionPort, 4, INVALID_HANDLE_VALUE, (uintptr)0, (uintptr)0, (uintptr)0); | |
39 if(cpiohandle == 0) { | |
40 runtime·printf("netpoll: failed to create cpio handle (errno=%d) \n", runtime·getlasterror()); | |
41 runtime·throw("netpoll: failed to create cpio handle"); | |
42 } | |
43 return; | |
44 } | |
45 | |
46 int32 | |
47 runtime·netpollopen(uintptr fd, PollDesc *pd) | |
48 { | |
49 USED(pd); | |
50 if(runtime·stdcall(runtime·CreateIoCompletionPort, 4, fd, cpiohandle, (u intptr)0, (uintptr)0) == 0) | |
51 return -runtime·getlasterror(); | |
52 return 0; | |
53 } | |
54 | |
55 int32 | |
56 runtime·netpollclose(uintptr fd) | |
57 { | |
58 // nothing to do | |
59 USED(fd); | |
60 return 0; | |
61 } | |
62 | |
63 // Polls for completed network IO. | |
64 // Returns list of goroutines that become runnable. | |
65 G* | |
66 runtime·netpoll(bool block) | |
67 { | |
68 uint32 wait, qty, key; | |
69 int32 mode, errno; | |
70 uintptr pd; | |
71 net_anOp *o; | |
72 G *gp; | |
73 | |
74 if(cpiohandle == INVALID_HANDLE_VALUE) | |
75 return nil; | |
76 o = nil; | |
77 errno = 0; | |
78 qty = 0; | |
79 wait = INFINITE; | |
80 if(!block) | |
81 wait = 0; | |
82 // TODO(brainman): Need a loop here to fetch all pending notifications | |
83 // (or at least a batch). Scheduler will behave better if is given | |
84 // a batch of newly runnable goroutines. | |
85 // TODO(brainman): Call GetQueuedCompletionStatusEx() here when possible . | |
dvyukov
2013/06/04 09:56:42
This is unrelated to this change, but I am eager t
brainman
2013/06/06 05:37:56
Will do.
| |
86 if(runtime·stdcall(runtime·GetQueuedCompletionStatus, 5, cpiohandle, &qt y, &key, &o, (uintptr)wait) == 0) { | |
87 errno = runtime·getlasterror(); | |
88 if(o == nil && errno == WAIT_TIMEOUT) { | |
89 if(!block) | |
90 return nil; | |
91 runtime·throw("netpoll: GetQueuedCompletionStatus timed out"); | |
92 } | |
93 if(o == nil) { | |
94 runtime·printf("netpoll: GetQueuedCompletionStatus faile d (errno=%d)\n", errno); | |
95 runtime·throw("netpoll: GetQueuedCompletionStatus failed "); | |
96 } | |
97 // dequeued failed IO packet, so report that | |
98 } | |
99 if(o == nil) | |
100 runtime·throw("netpoll: GetQueuedCompletionStatus returned o == nil"); | |
101 pd = o->runtimeCtx; | |
102 mode = o->mode; | |
103 if(mode != 'r' && mode != 'w') { | |
104 runtime·printf("netpoll: GetQueuedCompletionStatus returned inva lid mode=%d\n", mode); | |
105 runtime·throw("netpoll: GetQueuedCompletionStatus returned inval id mode"); | |
106 } | |
107 o->errno = errno; | |
108 o->qty = qty; | |
109 gp = nil; | |
110 runtime·netpollready(&gp, (void*)pd, mode); | |
111 return gp; | |
112 } | |
OLD | NEW |