Skip to content

Commit

Permalink
- New Win32Thread.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmpassos committed Aug 9, 2023
1 parent 0aa07c0 commit 5303d83
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- `Window`:
- Added `showMessage`, `showConfirmationDialog` and `showDialog`.
- Free some pointers.
- New `Win32Thread`.

## 1.0.9

Expand Down
68 changes: 68 additions & 0 deletions lib/src/win32_thread.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import 'dart:ffi';

import 'package:ffi/ffi.dart';
import 'package:win32/win32.dart';

// ignore_for_file: constant_identifier_names

/// Handles Win32 Thread creation:
class Win32Thread {
/// Creates a Win32 Thread.
/// - [threadFunction] is the entrypoint function of the Thread.
/// - [threadParam] is an optional parameter to be passed to [threadFunction].
static ({int threadID, int hThread})? createThread(
{required Pointer<NativeFunction<ThreadProc>> threadFunction,
Pointer<NativeType>? threadParam,
int flags = 0}) {
final threadIdPtr = calloc<Uint32>();

var hThread = CreateThread(
nullptr,
0,
threadFunction,
threadParam ?? nullptr,
flags,
threadIdPtr,
);

if (hThread == NULL) {
return null;
}

var threadId = threadIdPtr.value;

return (threadID: threadId, hThread: hThread);
}

static const WAIT_OBJECT_0 = 0x00000000;
static const WAIT_TIMEOUT = 0x00000102;
static const WAIT_ABANDONED = 0x00000080;
static const WAIT_FAILED = 0xFFFFFFFF;

/// Waits a thread to exit.
/// - Calls Win32 [WaitForSingleObject].
/// - Returns `null` if failed.
/// - Returns `true` if thread exited.
/// - Returns `false` on timeout.
static bool? waitThread(int hThread, {Duration? timeout}) {
int timeoutMs;
if (timeout != null) {
timeoutMs = timeout.inMilliseconds;
if (timeoutMs < 0) {
timeoutMs = 0;
}
} else {
timeoutMs = INFINITE;
}

var r = WaitForSingleObject(hThread, timeoutMs);

if (r == WAIT_OBJECT_0) {
return true;
} else if (r == WAIT_TIMEOUT) {
return false;
}

return null;
}
}
2 changes: 2 additions & 0 deletions lib/win32_gui.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ library win32_gui;

export 'dart:ffi';

export 'package:ffi/ffi.dart' hide StringUtf8Pointer;
export 'package:win32/win32.dart';

export 'src/components/win32_component_button.dart';
export 'src/components/win32_richedit.dart';
export 'src/win32_constants.dart';
export 'src/win32_constants_extra.dart';
export 'src/win32_gui_base.dart';
export 'src/win32_thread.dart';
27 changes: 27 additions & 0 deletions test/win32_thread_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@TestOn('windows')
import 'package:test/test.dart';
import 'package:win32_gui/win32_gui.dart';
import 'package:win32_gui/win32_gui_logging.dart';

int _threadFunction(Pointer<Utf16> param) {
return 0;
}

void main() {
logToConsole();

test('Win32 Thread', () async {
var t = Win32Thread.createThread(
threadFunction: Pointer.fromFunction<ThreadProc>(_threadFunction, 0),
threadParam: 'xyz'.toNativeUtf16());

expect(t, isNotNull);

expect(t!.hThread, isNot(equals(0)));
expect(t.threadID, isNot(equals(0)));

var tExited =
Win32Thread.waitThread(t.hThread, timeout: Duration(seconds: 1));
expect(tExited, isTrue);
});
}

0 comments on commit 5303d83

Please sign in to comment.