Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(926)

Side by Side Diff: mojo/public/dart/src/handle.dart

Issue 996923003: Dart: Better handle leak checks. close() is async. (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Fix regexes Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 part of core; 5 part of core;
6 6
7 class _MojoHandleNatives { 7 class _MojoHandleNatives {
8 static int register(MojoEventStream eventStream) native "MojoHandle_Register"; 8 static int register(MojoEventStream eventStream) native "MojoHandle_Register";
9 static int close(int handle) native "MojoHandle_Close"; 9 static int close(int handle) native "MojoHandle_Close";
10 static List wait( 10 static List wait(
11 int handle, int signals, int deadline) native "MojoHandle_Wait"; 11 int handle, int signals, int deadline) native "MojoHandle_Wait";
12 static List waitMany(List<int> handles, List<int> signals, 12 static List waitMany(List<int> handles, List<int> signals,
13 int deadline) native "MojoHandle_WaitMany"; 13 int deadline) native "MojoHandle_WaitMany";
14 } 14 }
15 15
16 class _HandleCreationRecord {
17 final MojoHandle handle;
18 final StackTrace stack;
19 _HandleCreationRecord(this.handle, this.stack);
20 }
21
16 class MojoHandle { 22 class MojoHandle {
17 static const int INVALID = 0; 23 static const int INVALID = 0;
18 static const int DEADLINE_INDEFINITE = -1; 24 static const int DEADLINE_INDEFINITE = -1;
19 25
20 int h; 26 int _h;
27 int get h => _h;
21 28
22 MojoHandle(this.h); 29 MojoHandle(this._h) {
30 assert(_addUnclosedHandle(this));
31 }
32
33 MojoHandle._internal(this._h);
34
35 MojoHandle.invalid() : this._internal(INVALID);
23 36
24 MojoResult close() { 37 MojoResult close() {
25 int result = _MojoHandleNatives.close(h); 38 assert(_removeUnclosedHandle(this));
26 h = INVALID; 39 int result = _MojoHandleNatives.close(_h);
40 _h = INVALID;
27 return new MojoResult(result); 41 return new MojoResult(result);
28 } 42 }
29 43
44 MojoHandle pass() {
45 assert(_removeUnclosedHandle(this));
46 return this;
47 }
48
30 MojoWaitResult wait(int signals, int deadline) { 49 MojoWaitResult wait(int signals, int deadline) {
31 List result = _MojoHandleNatives.wait(h, signals, deadline); 50 List result = _MojoHandleNatives.wait(h, signals, deadline);
32 return new MojoWaitResult(new MojoResult(result[0]), result[1]); 51 return new MojoWaitResult(new MojoResult(result[0]), result[1]);
33 } 52 }
34 53
35 bool _ready(MojoHandleSignals signal) { 54 bool _ready(MojoHandleSignals signal) {
36 MojoWaitResult mwr = wait(signal.value, 0); 55 MojoWaitResult mwr = wait(signal.value, 0);
37 switch (mwr.result) { 56 switch (mwr.result) {
38 case MojoResult.OK: 57 case MojoResult.OK:
39 return true; 58 return true;
40 case MojoResult.DEADLINE_EXCEEDED: 59 case MojoResult.DEADLINE_EXCEEDED:
41 case MojoResult.CANCELLED: 60 case MojoResult.CANCELLED:
42 case MojoResult.INVALID_ARGUMENT: 61 case MojoResult.INVALID_ARGUMENT:
43 case MojoResult.FAILED_PRECONDITION: 62 case MojoResult.FAILED_PRECONDITION:
44 return false; 63 return false;
45 default: 64 default:
46 // Should be unreachable. 65 // Should be unreachable.
47 throw "Unexpected result $res for wait on $h"; 66 throw "Unexpected result $mwr for wait on $h";
48 } 67 }
49 } 68 }
50 69
70 void _set(int value) {
71 _h = value;
72 }
73
51 bool get readyRead => _ready(MojoHandleSignals.PEER_CLOSED_READABLE); 74 bool get readyRead => _ready(MojoHandleSignals.PEER_CLOSED_READABLE);
52 bool get readyWrite => _ready(MojoHandleSignals.WRITABLE); 75 bool get readyWrite => _ready(MojoHandleSignals.WRITABLE);
76 bool get isValid => (_h != INVALID);
77
78 String toString() {
79 if (!isValid) {
80 return "MojoHandle(INVALID)";
81 }
82 var mwr = wait(MojoHandleSignals.kAll, 0);
83 return "MojoHandle(h: $h, status: $mwr)";
84 }
85
86 bool operator ==(MojoHandle other) {
87 return _h == other._h;
88 }
53 89
54 static MojoWaitManyResult waitMany( 90 static MojoWaitManyResult waitMany(
55 List<int> handles, List<int> signals, int deadline) { 91 List<int> handles, List<int> signals, int deadline) {
56 List result = _MojoHandleNatives.waitMany(handles, signals, deadline); 92 List result = _MojoHandleNatives.waitMany(handles, signals, deadline);
57 return new MojoWaitManyResult( 93 return new MojoWaitManyResult(
58 new MojoResult(result[0]), result[1], result[2]); 94 new MojoResult(result[0]), result[1], result[2]);
59 } 95 }
60 96
61 static MojoResult register(MojoEventStream eventStream) { 97 static MojoResult register(MojoEventStream eventStream) {
62 return new MojoResult(_MojoHandleNatives.register(eventStream)); 98 return new MojoResult(_MojoHandleNatives.register(eventStream));
63 } 99 }
64 100
65 bool get isValid => (h != INVALID); 101 static HashMap<int, _HandleCreationRecord> _unclosedHandles = new HashMap();
66 102
67 String toString() { 103 // _addUnclosedHandle(), _removeUnclosedHandle(), and dumpLeakedHandles()
68 if (!isValid) { 104 // should only be used inside of assert() statements.
69 return "MojoHandle(INVALID)"; 105 static bool _addUnclosedHandle(MojoHandle handle) {
106 var stack;
107 try {
108 assert(false);
sky 2015/03/11 17:17:57 Ick.
zra 2015/03/11 18:58:20 In case someone accidentally uses one of these cal
109 } catch (_, s) {
110 stack = s;
70 } 111 }
71 var mwr = wait(MojoHandleSignals.kAll, 0); 112
72 return "MojoHandle(h: $h, status: $mwr)"; 113 var handleCreate = new _HandleCreationRecord(handle, stack);
114 _unclosedHandles[handle.h] = handleCreate;
115 return true;
sky 2015/03/11 17:17:57 Is there a reason you have a return value here sin
zra 2015/03/11 18:58:20 Making these calls only inside of assert() stateme
sky 2015/03/11 19:17:24 Ah, tricky. Got it.
73 } 116 }
74 117
75 bool operator ==(MojoHandle other) { 118 static bool _removeUnclosedHandle(MojoHandle handle) {
76 return h == other.h; 119 _unclosedHandles.remove(handle._h);
120 return true;
sky 2015/03/11 17:17:57 Same comment here about always true return value.
zra 2015/03/11 18:58:20 Same reason.
121 }
122
123 static bool reportLeakedHandles() {
124 var noleaks = true;
125 for (var handle in MojoHandle._unclosedHandles.keys) {
126 var handleCreation = MojoHandle._unclosedHandles[handle];
127 if (handleCreation != null) {
128 print("HANDLE LEAK: handle: $handle, created at:");
129 print("${handleCreation.stack}");
130 noleaks = false;
131 }
132 }
133 return noleaks;
77 } 134 }
78 } 135 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698