Produced by Araxis Merge on 9/25/2018 2:13:22 PM Central Daylight Time. See www.araxis.com for information about Merge. This report uses XHTML and CSS2, and is best viewed with a modern standards-compliant browser. For optimum results when printing this report, use landscape orientation and enable printing of background images and colours in your browser.
# | Location | File | Last Modified |
---|---|---|---|
1 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\nio\fs | WindowsWatchService.java | Mon Jan 22 14:46:58 2018 UTC |
2 | build 3.zip\build 3\MHLTH_YS_137_Source\JavaScript\resources\javaJDF-1.8.0\src\sun\nio\fs | WindowsWatchService.java | Wed Sep 12 17:49:17 2018 UTC |
Description | Between Files 1 and 2 |
|
---|---|---|
Text Blocks | Lines | |
Unchanged | 2 | 1310 |
Changed | 1 | 2 |
Inserted | 0 | 0 |
Removed | 0 | 0 |
Whitespace | |
---|---|
Character case | Differences in character case are significant |
Line endings | Differences in line endings (CR and LF characters) are ignored |
CR/LF characters | Not shown in the comparison detail |
No regular expressions were active.
1 | /* | |
2 | * Copyrig ht (c) 200 8, 2013, O racle and/ or its aff iliates. A ll rights reserved. | |
3 | * DO NOT ALTER OR R EMOVE COPY RIGHT NOTI CES OR THI S FILE HEA DER. | |
4 | * | |
5 | * This co de is free software; you can r edistribut e it and/o r modify i t | |
6 | * under t he terms o f the GNU General Pu blic Licen se version 2 only, a s | |
7 | * publish ed by the Free Softw are Founda tion. Ora cle design ates this | |
8 | * particu lar file a s subject to the "Cl asspath" e xception a s provided | |
9 | * by Orac le in the LICENSE fi le that ac companied this code. | |
10 | * | |
11 | * This co de is dist ributed in the hope that it wi ll be usef ul, but WI THOUT | |
12 | * ANY WAR RANTY; wit hout even the implie d warranty of MERCHA NTABILITY or | |
13 | * FITNESS FOR A PAR TICULAR PU RPOSE. Se e the GNU General Pu blic Licen se | |
14 | * version 2 for mor e details (a copy is included in the LIC ENSE file that | |
15 | * accompa nied this code). | |
16 | * | |
17 | * You sho uld have r eceived a copy of th e GNU Gene ral Public License v ersion | |
18 | * 2 along with this work; if not, write to the Fr ee Softwar e Foundati on, | |
19 | * Inc., 5 1 Franklin St, Fifth Floor, Bo ston, MA 0 2110-1301 USA. | |
20 | * | |
21 | * Please contact Or acle, 500 Oracle Par kway, Redw ood Shores , CA 94065 USA | |
22 | * or visi t www.orac le.com if you need a dditional informatio n or have any | |
23 | * questio ns. | |
24 | */ | |
25 | ||
26 | package su n.nio.fs; | |
27 | ||
28 | import jav a.io.IOExc eption; | |
29 | import jav a.nio.file .NotDirect oryExcepti on; | |
30 | import jav a.nio.file .Path; | |
31 | import jav a.nio.file .StandardW atchEventK inds; | |
32 | import jav a.nio.file .WatchEven t; | |
33 | import jav a.nio.file .WatchKey; | |
34 | import jav a.util.Has hMap; | |
35 | import jav a.util.Map ; | |
36 | import jav a.util.Set ; | |
37 | ||
38 | import com .sun.nio.f ile.Extend edWatchEve ntModifier ; | |
39 | import sun .misc.Unsa fe; | |
40 | ||
41 | import sta tic sun.ni o.fs.Windo wsNativeDi spatcher.* ; | |
42 | import sta tic sun.ni o.fs.Windo wsConstant s.*; | |
43 | ||
44 | /* | |
45 | * Win32 i mplementat ion of Wat chService based on R eadDirecto ryChangesW . | |
46 | */ | |
47 | ||
48 | class Wind owsWatchSe rvice | |
49 | extend s Abstract WatchServi ce | |
50 | { | |
51 | privat e final st atic int W AKEUP_COMP LETION_KEY = 0; | |
52 | ||
53 | // bac kground th read to se rvice I/O completion port | |
54 | privat e final Po ller polle r; | |
55 | ||
56 | /** | |
57 | * Cre ates an I/ O completi on port an d a daemon thread to service i t | |
58 | */ | |
59 | Window sWatchServ ice(Window sFileSyste m fs) thro ws IOExcep tion { | |
60 | // create I/ O completi on port | |
61 | long PORT
|
|
62 | tr y { | |
63 | port = C reateIoCom pletionPor t(INVALID_ HANDLE_VAL UE, 0, 0); | |
64 | } catch (Win dowsExcept ion x) { | |
65 | throw ne w IOExcept ion(x.getM essage()); | |
66 | } | |
67 | ||
68 | th is.poller = new Poll er(fs, thi s, port); | |
69 | th is.poller. start(); | |
70 | } | |
71 | ||
72 | @Overr ide | |
73 | WatchK ey registe r(Path pat h, | |
74 | WatchEve nt.Kind<?> [] events, | |
75 | WatchEve nt.Modifie r... modif iers) | |
76 | t hrows IOEx ception | |
77 | { | |
78 | // delegate to poller | |
79 | re turn polle r.register (path, eve nts, modif iers); | |
80 | } | |
81 | ||
82 | @Overr ide | |
83 | void i mplClose() throws IO Exception { | |
84 | // delegate to poller | |
85 | po ller.close (); | |
86 | } | |
87 | ||
88 | /** | |
89 | * Win dows imple mentation of WatchKe y. | |
90 | */ | |
91 | privat e static c lass Windo wsWatchKey extends A bstractWat chKey { | |
92 | // file key (used to d etect exis ting regis trations) | |
93 | pr ivate fina l FileKey fileKey; | |
94 | ||
95 | // handle to directory | |
96 | pr ivate vola tile long handle = I NVALID_HAN DLE_VALUE; | |
97 | ||
98 | // interest events | |
99 | pr ivate Set< ? extends WatchEvent .Kind<?>> events; | |
100 | ||
101 | // subtree | |
102 | pr ivate bool ean watchS ubtree; | |
103 | ||
104 | // buffer fo r change e vents | |
105 | pr ivate Nati veBuffer b uffer; | |
106 | ||
107 | // pointer t o bytes re turned (in buffer) | |
108 | pr ivate long countAddr ess; | |
109 | ||
110 | // pointer t o overlapp ed structu re (in buf fer) | |
111 | pr ivate long overlappe dAddress; | |
112 | ||
113 | // completio n key (use d to map I /O complet ion to Wat chKey) | |
114 | pr ivate int completion Key; | |
115 | ||
116 | // flag indi cates that ReadDirec toryChange sW failed | |
117 | // and overl apped I/O operation wasn't sta rted | |
118 | pr ivate bool ean errorS tartingOve rlapped; | |
119 | ||
120 | Wi ndowsWatch Key(Path d ir, | |
121 | Abstra ctWatchSer vice watch er, | |
122 | FileKe y fileKey) | |
123 | { | |
124 | super(di r, watcher ); | |
125 | this.fil eKey = fil eKey; | |
126 | } | |
127 | ||
128 | Wi ndowsWatch Key init(l ong handle , | |
129 | S et<? exten ds WatchEv ent.Kind<? >> events, | |
130 | b oolean wat chSubtree, | |
131 | N ativeBuffe r buffer, | |
132 | l ong countA ddress, | |
133 | l ong overla ppedAddres s, | |
134 | i nt complet ionKey) | |
135 | { | |
136 | this.han dle = hand le; | |
137 | this.eve nts = even ts; | |
138 | this.wat chSubtree = watchSub tree; | |
139 | this.buf fer = buff er; | |
140 | this.cou ntAddress = countAdd ress; | |
141 | this.ove rlappedAdd ress = ove rlappedAdd ress; | |
142 | this.com pletionKey = complet ionKey; | |
143 | return t his; | |
144 | } | |
145 | ||
146 | lo ng handle( ) { | |
147 | return h andle; | |
148 | } | |
149 | ||
150 | Se t<? extend s WatchEve nt.Kind<?> > events() { | |
151 | return e vents; | |
152 | } | |
153 | ||
154 | vo id setEven ts(Set<? e xtends Wat chEvent.Ki nd<?>> eve nts) { | |
155 | this.eve nts = even ts; | |
156 | } | |
157 | ||
158 | bo olean watc hSubtree() { | |
159 | return w atchSubtre e; | |
160 | } | |
161 | ||
162 | Na tiveBuffer buffer() { | |
163 | return b uffer; | |
164 | } | |
165 | ||
166 | lo ng countAd dress() { | |
167 | return c ountAddres s; | |
168 | } | |
169 | ||
170 | lo ng overlap pedAddress () { | |
171 | return o verlappedA ddress; | |
172 | } | |
173 | ||
174 | Fi leKey file Key() { | |
175 | return f ileKey; | |
176 | } | |
177 | ||
178 | in t completi onKey() { | |
179 | return c ompletionK ey; | |
180 | } | |
181 | ||
182 | vo id setErro rStartingO verlapped( boolean va lue) { | |
183 | errorSta rtingOverl apped = va lue; | |
184 | } | |
185 | ||
186 | bo olean isEr rorStartin gOverlappe d() { | |
187 | return e rrorStarti ngOverlapp ed; | |
188 | } | |
189 | ||
190 | // Invalidat e the key, assumes t hat resour ces have b een releas ed | |
191 | vo id invalid ate() { | |
192 | ((Window sWatchServ ice)watche r()).polle r.releaseR esources(t his); | |
193 | handle = INVALID_H ANDLE_VALU E; | |
194 | buffer = null; | |
195 | countAdd ress = 0; | |
196 | overlapp edAddress = 0; | |
197 | errorSta rtingOverl apped = fa lse; | |
198 | } | |
199 | ||
200 | @O verride | |
201 | pu blic boole an isValid () { | |
202 | return h andle != I NVALID_HAN DLE_VALUE; | |
203 | } | |
204 | ||
205 | @O verride | |
206 | pu blic void cancel() { | |
207 | if (isVa lid()) { | |
208 | // d elegate to poller | |
209 | ((Wi ndowsWatch Service)wa tcher()).p oller.canc el(this); | |
210 | } | |
211 | } | |
212 | } | |
213 | ||
214 | // fil e key to u nique iden tify (open ) director y | |
215 | privat e static c lass FileK ey { | |
216 | pr ivate fina l int volS erialNumbe r; | |
217 | pr ivate fina l int file IndexHigh; | |
218 | pr ivate fina l int file IndexLow; | |
219 | ||
220 | Fi leKey(int volSerialN umber, int fileIndex High, int fileIndexL ow) { | |
221 | this.vol SerialNumb er = volSe rialNumber ; | |
222 | this.fil eIndexHigh = fileInd exHigh; | |
223 | this.fil eIndexLow = fileInde xLow; | |
224 | } | |
225 | ||
226 | @O verride | |
227 | pu blic int h ashCode() { | |
228 | return v olSerialNu mber ^ fil eIndexHigh ^ fileInd exLow; | |
229 | } | |
230 | ||
231 | @O verride | |
232 | pu blic boole an equals( Object obj ) { | |
233 | if (obj == this) | |
234 | retu rn true; | |
235 | if (!(ob j instance of FileKey )) | |
236 | retu rn false; | |
237 | FileKey other = (F ileKey)obj ; | |
238 | if (this .volSerial Number != other.volS erialNumbe r) return false; | |
239 | if (this .fileIndex High != ot her.fileIn dexHigh) r eturn fals e; | |
240 | return t his.fileIn dexLow == other.file IndexLow; | |
241 | } | |
242 | } | |
243 | ||
244 | // all change ev ents | |
245 | privat e static f inal int A LL_FILE_NO TIFY_EVENT S = | |
246 | FI LE_NOTIFY_ CHANGE_FIL E_NAME | | |
247 | FI LE_NOTIFY_ CHANGE_DIR _NAME | | |
248 | FI LE_NOTIFY_ CHANGE_ATT RIBUTES | | |
249 | FI LE_NOTIFY_ CHANGE_SIZ E | | |
250 | FI LE_NOTIFY_ CHANGE_LAS T_WRITE | | |
251 | FI LE_NOTIFY_ CHANGE_CRE ATION | | |
252 | FI LE_NOTIFY_ CHANGE_SEC URITY; | |
253 | ||
254 | /** | |
255 | * Bac kground th read to se rvice I/O completion port. | |
256 | */ | |
257 | privat e static c lass Polle r extends AbstractPo ller { | |
258 | pr ivate fina l static U nsafe UNSA FE = Unsaf e.getUnsaf e(); | |
259 | ||
260 | /* | |
261 | * typedef s truct _OVE RLAPPED { | |
262 | * ULONG _PTR Inte rnal; | |
263 | * ULONG _PTR Inte rnalHigh; | |
264 | * union { | |
265 | * s truct { DW ORD Offset ; DWORD Of fsetHigh; }; | |
266 | * P VOID Poin ter; | |
267 | * }; | |
268 | * HANDL E hEven t; | |
269 | * } OVERLAP PED; | |
270 | * / | |
271 | pr ivate stat ic final s hort SIZEO F_DWORD = 4; | |
272 | pr ivate stat ic final s hort SIZEO F_OVERLAPP ED = 32 ; // 20 on 32-bit | |
273 | pr ivate stat ic final s hort OFFSE TOF_HEVENT = | |
274 | (UNSAFE. addressSiz e() == 4) ? (short) 16 : 24; | |
275 | ||
276 | ||
277 | /* | |
278 | * typedef s truct _FIL E_NOTIFY_I NFORMATION { | |
279 | * DWORD NextEntry Offset; | |
280 | * DWORD Action; | |
281 | * DWORD FileNameL ength; | |
282 | * WCHAR FileName[ 1]; | |
283 | * } FileNam eLength; | |
284 | * / | |
285 | pr ivate stat ic final s hort OFFSE TOF_NEXTEN TRYOFFSET = 0; | |
286 | pr ivate stat ic final s hort OFFSE TOF_ACTION = 4; | |
287 | pr ivate stat ic final s hort OFFSE TOF_FILENA MELENGTH = 8; | |
288 | pr ivate stat ic final s hort OFFSE TOF_FILENA ME = 12; | |
289 | ||
290 | // size of p er-directo ry buffer for events (FIXME - make this configurab le) | |
291 | // Need to b e less tha n 4*16384 = 65536. D WORD align . | |
292 | pr ivate stat ic final i nt CHANGES _BUFFER_SI ZE = 16 * 1024; | |
293 | ||
294 | pr ivate fina l WindowsF ileSystem fs; | |
295 | pr ivate fina l WindowsW atchServic e watcher; | |
296 | pr ivate fina l long por t; | |
297 | ||
298 | // maps comp letion key to WatchK ey | |
299 | pr ivate fina l Map<Inte ger, Windo wsWatchKey > ck2key; | |
300 | ||
301 | // maps file key to Wa tchKey | |
302 | pr ivate fina l Map<File Key, Windo wsWatchKey > fk2key; | |
303 | ||
304 | // unique co mpletion k ey for eac h director y | |
305 | // native co mpletion k ey capacit y is 64 bi ts on Win6 4. | |
306 | pr ivate int lastComple tionKey; | |
307 | ||
308 | Po ller(Windo wsFileSyst em fs, Win dowsWatchS ervice wat cher, long port) { | |
309 | this.fs = fs; | |
310 | this.wat cher = wat cher; | |
311 | this.por t = port; | |
312 | this.ck2 key = new HashMap<>( ); | |
313 | this.fk2 key = new HashMap<>( ); | |
314 | this.las tCompletio nKey = 0; | |
315 | } | |
316 | ||
317 | @O verride | |
318 | vo id wakeup( ) throws I OException { | |
319 | try { | |
320 | Post QueuedComp letionStat us(port, W AKEUP_COMP LETION_KEY ); | |
321 | } catch (WindowsEx ception x) { | |
322 | thro w new IOEx ception(x. getMessage ()); | |
323 | } | |
324 | } | |
325 | ||
326 | /* * | |
327 | * Register a director y for chan ges as fol lows: | |
328 | * | |
329 | * 1. Open d irectory | |
330 | * 2. Read i ts attribu tes (and c heck it re ally is a directory) | |
331 | * 3. Assign completio n key and associated handle wi th complet ion port | |
332 | * 4. Call R eadDirecto ryChangesW to start (async) re ad of chan ges | |
333 | * 5. Create or return existing key repres enting reg istration | |
334 | * / | |
335 | @O verride | |
336 | Ob ject implR egister(Pa th obj, | |
337 | Se t<? extend s WatchEve nt.Kind<?> > events, | |
338 | Wa tchEvent.M odifier... modifiers ) | |
339 | { | |
340 | WindowsP ath dir = (WindowsPa th)obj; | |
341 | boolean watchSubtr ee = false ; | |
342 | ||
343 | // FILE_ TREE modif ier allowe d | |
344 | for (Wat chEvent.Mo difier mod ifier: mod ifiers) { | |
345 | if ( modifier = = Extended WatchEvent Modifier.F ILE_TREE) { | |
346 | watchSubtr ee = true; | |
347 | } el se { | |
348 | if (modifi er == null ) | |
349 | return new NullP ointerExce ption(); | |
350 | if (modifi er instanc eof com.su n.nio.file .Sensitivi tyWatchEve ntModifier ) | |
351 | contin ue; // ign ore | |
352 | return new Unsupport edOperatio nException ("Modifier not suppo rted"); | |
353 | } | |
354 | } | |
355 | ||
356 | // open directory | |
357 | long han dle; | |
358 | try { | |
359 | hand le = Creat eFile(dir. getPathFor Win32Calls (), | |
360 | FILE _LIST_DIRE CTORY, | |
361 | (FIL E_SHARE_RE AD | FILE_ SHARE_WRIT E | FILE_S HARE_DELET E), | |
362 | OPEN _EXISTING, | |
363 | FILE _FLAG_BACK UP_SEMANTI CS | FILE_ FLAG_OVERL APPED); | |
364 | } catch (WindowsEx ception x) { | |
365 | retu rn x.asIOE xception(d ir); | |
366 | } | |
367 | ||
368 | boolean registered = false; | |
369 | try { | |
370 | // r ead attrib utes and c heck file is a direc tory | |
371 | Wind owsFileAtt ributes at trs; | |
372 | try { | |
373 | attrs = Wi ndowsFileA ttributes. readAttrib utes(handl e); | |
374 | } ca tch (Windo wsExceptio n x) { | |
375 | return x.a sIOExcepti on(dir); | |
376 | } | |
377 | if ( !attrs.isD irectory() ) { | |
378 | return new NotDirect oryExcepti on(dir.get PathForExc eptionMess age()); | |
379 | } | |
380 | ||
381 | // c heck if th is directo ry is alre ady regist ered | |
382 | File Key fk = n ew FileKey (attrs.vol SerialNumb er(), | |
383 | attrs.fil eIndexHigh (), | |
384 | attrs.fil eIndexLow( )); | |
385 | Wind owsWatchKe y existing = fk2key. get(fk); | |
386 | ||
387 | // i f already registered and we're not chang ing the su btree | |
388 | // m odifier th en simply update the event and return th e key. | |
389 | if ( existing ! = null && watchSubtr ee == exis ting.watch Subtree()) { | |
390 | existing.s etEvents(e vents); | |
391 | return exi sting; | |
392 | } | |
393 | ||
394 | // C an overflo w the int type capac ity. | |
395 | // S kip WAKEUP _COMPLETIO N_KEY valu e. | |
396 | int completion Key = ++la stCompleti onKey; | |
397 | if ( completion Key == WAK EUP_COMPLE TION_KEY) | |
398 | completion Key = ++la stCompleti onKey; | |
399 | ||
400 | // a ssociate h andle with completio n port | |
401 | try { | |
402 | CreateIoCo mpletionPo rt(handle, port, com pletionKey ); | |
403 | } ca tch (Windo wsExceptio n x) { | |
404 | return new IOExcepti on(x.getMe ssage()); | |
405 | } | |
406 | ||
407 | // a llocate me mory for e vents, inc luding spa ce for oth er structu res | |
408 | // n eeded to d o overlapp ed I/O | |
409 | int size = CHA NGES_BUFFE R_SIZE + S IZEOF_DWOR D + SIZEOF _OVERLAPPE D; | |
410 | Nati veBuffer b uffer = Na tiveBuffer s.getNativ eBuffer(si ze); | |
411 | ||
412 | long bufferAdd ress = buf fer.addres s(); | |
413 | long overlappe dAddress = bufferAdd ress + siz e - SIZEOF _OVERLAPPE D; | |
414 | long countAddr ess = over lappedAddr ess - SIZE OF_DWORD; | |
415 | ||
416 | // z ero the ov erlapped s tructure | |
417 | UNSA FE.setMemo ry(overlap pedAddress , SIZEOF_O VERLAPPED, (byte)0); | |
418 | ||
419 | // s tart async read of c hanges to directory | |
420 | try { | |
421 | createAndA ttachEvent (overlappe dAddress); | |
422 | ||
423 | ReadDirect oryChanges W(handle, | |
424 | bufferAd dress, | |
425 | CHANGES_ BUFFER_SIZ E, | |
426 | watchSub tree, | |
427 | ALL_FILE _NOTIFY_EV ENTS, | |
428 | countAdd ress, | |
429 | overlapp edAddress) ; | |
430 | } ca tch (Windo wsExceptio n x) { | |
431 | closeAttac hedEvent(o verlappedA ddress); | |
432 | buffer.rel ease(); | |
433 | return new IOExcepti on(x.getMe ssage()); | |
434 | } | |
435 | ||
436 | Wind owsWatchKe y watchKey ; | |
437 | if ( existing = = null) { | |
438 | // not reg istered so create ne w watch ke y | |
439 | watchKey = new Windo wsWatchKey (dir, watc her, fk) | |
440 | .init( handle, ev ents, watc hSubtree, buffer, co untAddress , | |
441 | overlapped Address, c ompletionK ey); | |
442 | // map fil e key to w atch key | |
443 | fk2key.put (fk, watch Key); | |
444 | } el se { | |
445 | // directo ry already registere d so need to: | |
446 | // 1. remo ve mapping from old completion key to ex isting wat ch key | |
447 | // 2. rele ase existi ng key's r esources ( handle/buf fer) | |
448 | // 3. re-i nitialize key with n ew handle/ buffer | |
449 | ck2key.rem ove(existi ng.complet ionKey()); | |
450 | releaseRes ources(exi sting); | |
451 | watchKey = existing. init(handl e, events, watchSubt ree, buffe r, | |
452 | countA ddress, ov erlappedAd dress, com pletionKey ); | |
453 | } | |
454 | // m ap complet ion map to watch key | |
455 | ck2k ey.put(com pletionKey , watchKey ); | |
456 | ||
457 | regi stered = t rue; | |
458 | retu rn watchKe y; | |
459 | ||
460 | } finall y { | |
461 | if ( !registere d) CloseHa ndle(handl e); | |
462 | } | |
463 | } | |
464 | ||
465 | /* * | |
466 | * Cancels t he outstan ding I/O o peration o n the dire ctory | |
467 | * associate d with the given key and relea ses the as sociated | |
468 | * resources . | |
469 | * / | |
470 | pr ivate void releaseRe sources(Wi ndowsWatch Key key) { | |
471 | if (!key .isErrorSt artingOver lapped()) { | |
472 | try { | |
473 | CancelIo(k ey.handle( )); | |
474 | GetOverlap pedResult( key.handle (), key.ov erlappedAd dress()); | |
475 | } ca tch (Windo wsExceptio n expected ) { | |
476 | // expecte d as I/O o peration h as been ca ncelled | |
477 | } | |
478 | } | |
479 | CloseHan dle(key.ha ndle()); | |
480 | closeAtt achedEvent (key.overl appedAddre ss()); | |
481 | key.buff er().clean er().clean (); | |
482 | } | |
483 | ||
484 | /* * | |
485 | * Creates a n unnamed event and set it as the hEvent field | |
486 | * in the gi ven OVERLA PPED struc ture | |
487 | * / | |
488 | pr ivate void createAnd AttachEven t(long ov) throws Wi ndowsExcep tion { | |
489 | long hEv ent = Crea teEvent(fa lse, false ); | |
490 | UNSAFE.p utAddress( ov + OFFSE TOF_HEVENT , hEvent); | |
491 | } | |
492 | ||
493 | /* * | |
494 | * Closes th e event at tached to the given OVERLAPPED structure . A | |
495 | * no-op if there isn' t an event attached. | |
496 | * / | |
497 | pr ivate void closeAtta chedEvent( long ov) { | |
498 | long hEv ent = UNSA FE.getAddr ess(ov + O FFSETOF_HE VENT); | |
499 | if (hEve nt != 0 && hEvent != INVALID_H ANDLE_VALU E) | |
500 | Close Handle(hEv ent); | |
501 | } | |
502 | ||
503 | // cancel si ngle key | |
504 | @O verride | |
505 | vo id implCan celKey(Wat chKey obj) { | |
506 | WindowsW atchKey ke y = (Windo wsWatchKey )obj; | |
507 | if (key. isValid()) { | |
508 | fk2k ey.remove( key.fileKe y()); | |
509 | ck2k ey.remove( key.comple tionKey()) ; | |
510 | key. invalidate (); | |
511 | } | |
512 | } | |
513 | ||
514 | // close wat ch service | |
515 | @O verride | |
516 | vo id implClo seAll() { | |
517 | // cance l all keys | |
518 | ck2key.v alues().fo rEach(Wind owsWatchKe y::invalid ate); | |
519 | ||
520 | fk2key.c lear(); | |
521 | ck2key.c lear(); | |
522 | ||
523 | // close I/O compl etion port | |
524 | CloseHan dle(port); | |
525 | } | |
526 | ||
527 | // Translate file chan ge action into watch event | |
528 | pr ivate Watc hEvent.Kin d<?> trans lateAction ToEvent(in t action) { | |
529 | switch ( action) { | |
530 | case FILE_ACTI ON_MODIFIE D : | |
531 | return Sta ndardWatch EventKinds .ENTRY_MOD IFY; | |
532 | ||
533 | case FILE_ACTI ON_ADDED : | |
534 | case FILE_ACTI ON_RENAMED _NEW_NAME : | |
535 | return Sta ndardWatch EventKinds .ENTRY_CRE ATE; | |
536 | ||
537 | case FILE_ACTI ON_REMOVED : | |
538 | case FILE_ACTI ON_RENAMED _OLD_NAME : | |
539 | return Sta ndardWatch EventKinds .ENTRY_DEL ETE; | |
540 | ||
541 | defa ult : | |
542 | return nul l; // act ion not re cognized | |
543 | } | |
544 | } | |
545 | ||
546 | // process e vents (lis t of FILE_ NOTIFY_INF ORMATION s tructures) | |
547 | pr ivate void processEv ents(Windo wsWatchKey key, int size) { | |
548 | long add ress = key .buffer(). address(); | |
549 | ||
550 | int next Offset; | |
551 | do { | |
552 | int action = U NSAFE.getI nt(address + OFFSETO F_ACTION); | |
553 | ||
554 | // m ap action to event | |
555 | Watc hEvent.Kin d<?> kind = translat eActionToE vent(actio n); | |
556 | if ( key.events ().contain s(kind)) { | |
557 | // copy th e name | |
558 | int nameLe ngthInByte s = UNSAFE .getInt(ad dress + OF FSETOF_FIL ENAMELENGT H); | |
559 | if ((nameL engthInByt es % 2) != 0) { | |
560 | throw new Assert ionError(" FileNameLe ngth is no t a multip le of 2"); | |
561 | } | |
562 | char[] nam eAsArray = new char[ nameLength InBytes/2] ; | |
563 | UNSAFE.cop yMemory(nu ll, addres s + OFFSET OF_FILENAM E, nameAsA rray, | |
564 | Unsafe .ARRAY_CHA R_BASE_OFF SET, nameL engthInByt es); | |
565 | ||
566 | // create FileName a nd queue e vent | |
567 | WindowsPat h name = W indowsPath | |
568 | .creat eFromNorma lizedPath( fs, new St ring(nameA sArray)); | |
569 | key.signal Event(kind , name); | |
570 | } | |
571 | ||
572 | // n ext event | |
573 | next Offset = U NSAFE.getI nt(address + OFFSETO F_NEXTENTR YOFFSET); | |
574 | addr ess += (lo ng)nextOff set; | |
575 | } while (nextOffse t != 0); | |
576 | } | |
577 | ||
578 | /* * | |
579 | * Poller ma in loop | |
580 | * / | |
581 | @O verride | |
582 | pu blic void run() { | |
583 | for (;;) { | |
584 | Comp letionStat us info; | |
585 | try { | |
586 | info = Get QueuedComp letionStat us(port); | |
587 | } ca tch (Windo wsExceptio n x) { | |
588 | // this sh ould not h appen | |
589 | x.printSta ckTrace(); | |
590 | return; | |
591 | } | |
592 | ||
593 | // w akeup | |
594 | if ( info.compl etionKey() == WAKEUP _COMPLETIO N_KEY) { | |
595 | boolean sh utdown = p rocessRequ ests(); | |
596 | if (shutdo wn) { | |
597 | return ; | |
598 | } | |
599 | continue; | |
600 | } | |
601 | ||
602 | // m ap complet ionKey to get WatchK ey | |
603 | Wind owsWatchKe y key = ck 2key.get(( int)info.c ompletionK ey()); | |
604 | if ( key == nul l) { | |
605 | // We get here when a registra tion is ch anged. In that case | |
606 | // the dir ectory is closed whi ch causes an event w ith the | |
607 | // old com pletion ke y. | |
608 | continue; | |
609 | } | |
610 | ||
611 | bool ean critic alError = false; | |
612 | int errorCode = info.err or(); | |
613 | int messageSiz e = info.b ytesTransf erred(); | |
614 | if ( errorCode == ERROR_N OTIFY_ENUM _DIR) { | |
615 | // buffer overflow | |
616 | key.signal Event(Stan dardWatchE ventKinds. OVERFLOW, null); | |
617 | } el se if (err orCode != 0 && error Code != ER ROR_MORE_D ATA) { | |
618 | // ReadDir ectoryChan gesW faile d | |
619 | criticalEr ror = true ; | |
620 | } el se { | |
621 | // ERROR_M ORE_DATA i s a warnin g about in complite | |
622 | // data tr ansfer ove r TCP/UDP stack. For the case | |
623 | // [messag eSize] is zero in th e most of cases. | |
624 | ||
625 | if (messag eSize > 0) { | |
626 | // pro cess non-e mpty event s. | |
627 | proces sEvents(ke y, message Size); | |
628 | } else if (errorCode == 0) { | |
629 | // ins ufficient buffer siz e | |
630 | // not described , but can happen. | |
631 | key.si gnalEvent( StandardWa tchEventKi nds.OVERFL OW, null); | |
632 | } | |
633 | ||
634 | // start r ead for ne xt batch o f changes | |
635 | try { | |
636 | ReadDi rectoryCha ngesW(key. handle(), | |
637 | key. buffer().a ddress(), | |
638 | CHAN GES_BUFFER _SIZE, | |
639 | key. watchSubtr ee(), | |
640 | ALL_ FILE_NOTIF Y_EVENTS, | |
641 | key. countAddre ss(), | |
642 | key. overlapped Address()) ; | |
643 | } catch (W indowsExce ption x) { | |
644 | // no choice but to cancel key | |
645 | critic alError = true; | |
646 | key.se tErrorStar tingOverla pped(true) ; | |
647 | } | |
648 | } | |
649 | if ( criticalEr ror) { | |
650 | implCancel Key(key); | |
651 | key.signal (); | |
652 | } | |
653 | } | |
654 | } | |
655 | } | |
656 | } |
Araxis Merge (but not the data content of this report) is Copyright © 1993-2016 Araxis Ltd (www.araxis.com). All rights reserved.