Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 7526473

Browse files
author
Pallavi Taneja
committed
Fix Issue#2808 : Support writing colored messages to console in a multi-threaded environment
In the System.Console portable library SyncTextReader/SyncTextWriter (the reader and writer used by the Console) locked on a private lock object which prevented users from writing colored console messages in sync with non-colored writers. Note this behavior was a regression from the Desktop where this could be achieved by locking against Console.Out which resulted in locking the writer APIs since the SyncTextWriter internally locked on itself. Although this approach is formed via an implementation detail, however this sceanrio is useful and there exists no work-around for it in the portable library. Hence, moving back to the earlier implementation, where the readers and writers locked against themselves instead of a private object.
1 parent 29d76d3 commit 7526473

File tree

4 files changed

+97
-42
lines changed

4 files changed

+97
-42
lines changed

src/System.Console/src/System/IO/SyncTextReader.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@
88

99
namespace System.IO
1010
{
11+
/* SyncTextReader intentionally locks on itself rather than a private lock object.
12+
* This is done to synchronize different console readers(Issue#2855).
13+
*/
1114
internal sealed class SyncTextReader : TextReader
1215
{
1316
private readonly TextReader _in;
14-
private readonly object _methodLock = new object();
1517

1618
public static SyncTextReader GetSynchronizedTextReader(TextReader reader)
1719
{
@@ -29,7 +31,7 @@ protected override void Dispose(bool disposing)
2931
{
3032
if (disposing)
3133
{
32-
lock (_methodLock)
34+
lock (this)
3335
{
3436
_in.Dispose();
3537
}
@@ -38,47 +40,47 @@ protected override void Dispose(bool disposing)
3840

3941
public override int Peek()
4042
{
41-
lock (_methodLock)
43+
lock (this)
4244
{
4345
return _in.Peek();
4446
}
4547
}
4648

4749
public override int Read()
4850
{
49-
lock (_methodLock)
51+
lock (this)
5052
{
5153
return _in.Read();
5254
}
5355
}
5456

5557
public override int Read([In, Out] char[] buffer, int index, int count)
5658
{
57-
lock (_methodLock)
59+
lock (this)
5860
{
5961
return _in.Read(buffer, index, count);
6062
}
6163
}
6264

6365
public override int ReadBlock([In, Out] char[] buffer, int index, int count)
6466
{
65-
lock (_methodLock)
67+
lock (this)
6668
{
6769
return _in.ReadBlock(buffer, index, count);
6870
}
6971
}
7072

7173
public override String ReadLine()
7274
{
73-
lock (_methodLock)
75+
lock (this)
7476
{
7577
return _in.ReadLine();
7678
}
7779
}
7880

7981
public override String ReadToEnd()
8082
{
81-
lock (_methodLock)
83+
lock (this)
8284
{
8385
return _in.ReadToEnd();
8486
}

src/System.Console/src/System/IO/SyncTextWriter.cs

Lines changed: 38 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@
77

88
namespace System.IO
99
{
10+
/* SyncTextWriter intentionally locks on itself rather than a private lock object.
11+
* This is done to synchronize different console writers.
12+
* For example - colored console writers can be synchronized with non-colored
13+
* writers by locking on Console.On (Issue#2855).
14+
*/
1015
internal sealed class SyncTextWriter : TextWriter, IDisposable
1116
{
12-
private readonly object _methodLock = new object();
1317
internal readonly TextWriter _out;
1418

1519
internal static SyncTextWriter GetSynchronizedTextWriter(TextWriter writer)
@@ -37,15 +41,15 @@ public override IFormatProvider FormatProvider
3741

3842
public override String NewLine
3943
{
40-
get { lock (_methodLock) { return _out.NewLine; } }
41-
set { lock (_methodLock) { _out.NewLine = value; } }
44+
get { lock (this) { return _out.NewLine; } }
45+
set { lock (this) { _out.NewLine = value; } }
4246
}
4347

4448
protected override void Dispose(bool disposing)
4549
{
4650
if (disposing)
4751
{
48-
lock (_methodLock)
52+
lock (this)
4953
{
5054
_out.Dispose();
5155
}
@@ -54,239 +58,239 @@ protected override void Dispose(bool disposing)
5458

5559
public override void Flush()
5660
{
57-
lock (_methodLock)
61+
lock (this)
5862
{
5963
_out.Flush();
6064
}
6165
}
6266

6367
public override void Write(char value)
6468
{
65-
lock (_methodLock)
69+
lock (this)
6670
{
6771
_out.Write(value);
6872
}
6973
}
7074

7175
public override void Write(char[] buffer)
7276
{
73-
lock (_methodLock)
77+
lock (this)
7478
{
7579
_out.Write(buffer);
7680
}
7781
}
7882

7983
public override void Write(char[] buffer, int index, int count)
8084
{
81-
lock (_methodLock)
85+
lock (this)
8286
{
8387
_out.Write(buffer, index, count);
8488
}
8589
}
8690

8791
public override void Write(bool value)
8892
{
89-
lock (_methodLock)
93+
lock (this)
9094
{
9195
_out.Write(value);
9296
}
9397
}
9498

9599
public override void Write(int value)
96100
{
97-
lock (_methodLock)
101+
lock (this)
98102
{
99103
_out.Write(value);
100104
}
101105
}
102106

103107
public override void Write(uint value)
104108
{
105-
lock (_methodLock)
109+
lock (this)
106110
{
107111
_out.Write(value);
108112
}
109113
}
110114

111115
public override void Write(long value)
112116
{
113-
lock (_methodLock)
117+
lock (this)
114118
{
115119
_out.Write(value);
116120
}
117121
}
118122

119123
public override void Write(ulong value)
120124
{
121-
lock (_methodLock)
125+
lock (this)
122126
{
123127
_out.Write(value);
124128
}
125129
}
126130

127131
public override void Write(float value)
128132
{
129-
lock (_methodLock)
133+
lock (this)
130134
{
131135
_out.Write(value);
132136
}
133137
}
134138

135139
public override void Write(double value)
136140
{
137-
lock (_methodLock)
141+
lock (this)
138142
{
139143
_out.Write(value);
140144
}
141145
}
142146

143147
public override void Write(Decimal value)
144148
{
145-
lock (_methodLock)
149+
lock (this)
146150
{
147151
_out.Write(value);
148152
}
149153
}
150154

151155
public override void Write(String value)
152156
{
153-
lock (_methodLock)
157+
lock (this)
154158
{
155159
_out.Write(value);
156160
}
157161
}
158162

159163
public override void Write(Object value)
160164
{
161-
lock (_methodLock)
165+
lock (this)
162166
{
163167
_out.Write(value);
164168
}
165169
}
166170

167171
public override void Write(String format, Object[] arg)
168172
{
169-
lock (_methodLock)
173+
lock (this)
170174
{
171175
_out.Write(format, arg);
172176
}
173177
}
174178

175179
public override void WriteLine()
176180
{
177-
lock (_methodLock)
181+
lock (this)
178182
{
179183
_out.WriteLine();
180184
}
181185
}
182186

183187
public override void WriteLine(char value)
184188
{
185-
lock (_methodLock)
189+
lock (this)
186190
{
187191
_out.WriteLine(value);
188192
}
189193
}
190194

191195
public override void WriteLine(decimal value)
192196
{
193-
lock (_methodLock)
197+
lock (this)
194198
{
195199
_out.WriteLine(value);
196200
}
197201
}
198202

199203
public override void WriteLine(char[] buffer)
200204
{
201-
lock (_methodLock)
205+
lock (this)
202206
{
203207
_out.WriteLine(buffer);
204208
}
205209
}
206210

207211
public override void WriteLine(char[] buffer, int index, int count)
208212
{
209-
lock (_methodLock)
213+
lock (this)
210214
{
211215
_out.WriteLine(buffer, index, count);
212216
}
213217
}
214218

215219
public override void WriteLine(bool value)
216220
{
217-
lock (_methodLock)
221+
lock (this)
218222
{
219223
_out.WriteLine(value);
220224
}
221225
}
222226

223227
public override void WriteLine(int value)
224228
{
225-
lock (_methodLock)
229+
lock (this)
226230
{
227231
_out.WriteLine(value);
228232
}
229233
}
230234

231235
public override void WriteLine(uint value)
232236
{
233-
lock (_methodLock)
237+
lock (this)
234238
{
235239
_out.WriteLine(value);
236240
}
237241
}
238242

239243
public override void WriteLine(long value)
240244
{
241-
lock (_methodLock)
245+
lock (this)
242246
{
243247
_out.WriteLine(value);
244248
}
245249
}
246250

247251
public override void WriteLine(ulong value)
248252
{
249-
lock (_methodLock)
253+
lock (this)
250254
{
251255
_out.WriteLine(value);
252256
}
253257
}
254258

255259
public override void WriteLine(float value)
256260
{
257-
lock (_methodLock)
261+
lock (this)
258262
{
259263
_out.WriteLine(value);
260264
}
261265
}
262266

263267
public override void WriteLine(double value)
264268
{
265-
lock (_methodLock)
269+
lock (this)
266270
{
267271
_out.WriteLine(value);
268272
}
269273
}
270274

271275
public override void WriteLine(String value)
272276
{
273-
lock (_methodLock)
277+
lock (this)
274278
{
275279
_out.WriteLine(value);
276280
}
277281
}
278282

279283
public override void WriteLine(Object value)
280284
{
281-
lock (_methodLock)
285+
lock (this)
282286
{
283287
_out.WriteLine(value);
284288
}
285289
}
286290

287291
public override void WriteLine(String format, Object[] arg)
288292
{
289-
lock (_methodLock)
293+
lock (this)
290294
{
291295
_out.WriteLine(format, arg);
292296
}

0 commit comments

Comments
 (0)