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

Commit 197679e

Browse files
jkotassafern
authored andcommitted
Simplify and unify EnumCalendars interop (dotnet/coreclr#15762)
Windows was not allocating GCHandles, switch Unix to do the same. Signed-off-by: dotnet-bot-corefx-mirror <dotnet-bot@microsoft.com>
1 parent 5471a4b commit 197679e

File tree

2 files changed

+19
-31
lines changed

2 files changed

+19
-31
lines changed

src/Common/src/CoreLib/System/Globalization/CalendarData.Unix.cs

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
using System.Collections.Generic;
66
using System.Diagnostics;
7-
using System.Runtime.InteropServices;
87
using System.Security;
98
using System.Text;
9+
using Internal.Runtime.CompilerServices;
1010

1111
namespace System.Globalization
1212
{
@@ -109,9 +109,10 @@ private static bool EnumDatePatterns(string localeName, CalendarId calendarId, C
109109
{
110110
datePatterns = null;
111111

112-
CallbackContext callbackContext = new CallbackContext();
112+
EnumCalendarsData callbackContext = new EnumCalendarsData();
113+
callbackContext.Results = new List<string>();
113114
callbackContext.DisallowDuplicates = true;
114-
bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
115+
bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext);
115116
if (result)
116117
{
117118
List<string> datePatternsList = callbackContext.Results;
@@ -244,8 +245,9 @@ private static bool EnumMonthNames(string localeName, CalendarId calendarId, Cal
244245
{
245246
monthNames = null;
246247

247-
CallbackContext callbackContext = new CallbackContext();
248-
bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
248+
EnumCalendarsData callbackContext = new EnumCalendarsData();
249+
callbackContext.Results = new List<string>();
250+
bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext);
249251
if (result)
250252
{
251253
// the month-name arrays are expected to have 13 elements. If ICU only returns 12, add an
@@ -280,8 +282,9 @@ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId,
280282
{
281283
calendarData = null;
282284

283-
CallbackContext callbackContext = new CallbackContext();
284-
bool result = EnumCalendarInfo(localeName, calendarId, dataType, callbackContext);
285+
EnumCalendarsData callbackContext = new EnumCalendarsData();
286+
callbackContext.Results = new List<string>();
287+
bool result = EnumCalendarInfo(localeName, calendarId, dataType, ref callbackContext);
285288
if (result)
286289
{
287290
calendarData = callbackContext.Results.ToArray();
@@ -290,24 +293,16 @@ internal static bool EnumCalendarInfo(string localeName, CalendarId calendarId,
290293
return result;
291294
}
292295

293-
private static bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, CallbackContext callbackContext)
296+
private static unsafe bool EnumCalendarInfo(string localeName, CalendarId calendarId, CalendarDataType dataType, ref EnumCalendarsData callbackContext)
294297
{
295-
GCHandle context = GCHandle.Alloc(callbackContext);
296-
try
297-
{
298-
return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)context);
299-
}
300-
finally
301-
{
302-
context.Free();
303-
}
298+
return Interop.GlobalizationInterop.EnumCalendarInfo(EnumCalendarInfoCallback, localeName, calendarId, dataType, (IntPtr)Unsafe.AsPointer(ref callbackContext));
304299
}
305300

306-
private static void EnumCalendarInfoCallback(string calendarString, IntPtr context)
301+
private static unsafe void EnumCalendarInfoCallback(string calendarString, IntPtr context)
307302
{
308303
try
309304
{
310-
CallbackContext callbackContext = (CallbackContext)((GCHandle)context).Target;
305+
ref EnumCalendarsData callbackContext = ref Unsafe.As<byte, EnumCalendarsData>(ref *(byte*)context);
311306

312307
if (callbackContext.DisallowDuplicates)
313308
{
@@ -331,17 +326,10 @@ private static void EnumCalendarInfoCallback(string calendarString, IntPtr conte
331326
}
332327
}
333328

334-
private class CallbackContext
329+
private struct EnumCalendarsData
335330
{
336-
private List<string> _results = new List<string>();
337-
338-
public CallbackContext()
339-
{
340-
}
341-
342-
public List<string> Results { get { return _results; } }
343-
344-
public bool DisallowDuplicates { get; set; }
331+
public List<string> Results;
332+
public bool DisallowDuplicates;
345333
}
346334
}
347335
}

src/Common/src/CoreLib/System/Globalization/CalendarData.Windows.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ private static unsafe bool CallGetCalendarInfoEx(string localeName, CalendarId c
274274
}
275275

276276
// Context for EnumCalendarInfoExEx callback.
277-
private class EnumData
277+
private struct EnumData
278278
{
279279
public string userOverride;
280280
public List<string> strings;
@@ -427,7 +427,7 @@ private static bool GetCalendarMonthInfo(string localeName, CalendarId calendar,
427427
//
428428
// struct to help our calendar data enumaration callback
429429
//
430-
private class EnumCalendarsData
430+
private struct EnumCalendarsData
431431
{
432432
public int userOverride; // user override value (if found)
433433
public List<int> calendars; // list of calendars found so far

0 commit comments

Comments
 (0)