...
Run Format

Text file src/runtime/cgo/gcc_libinit_windows.c

Documentation: runtime/cgo

     1	// Copyright 2015 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	// +build cgo
     6	#define WIN64_LEAN_AND_MEAN
     7	#include <windows.h>
     8	#include <process.h>
     9	
    10	#include <stdio.h>
    11	#include <stdlib.h>
    12	
    13	#include "libcgo.h"
    14	
    15	static volatile LONG runtime_init_once_gate = 0;
    16	static volatile LONG runtime_init_once_done = 0;
    17	
    18	static CRITICAL_SECTION runtime_init_cs;
    19	
    20	static HANDLE runtime_init_wait;
    21	static int runtime_init_done;
    22	
    23	// Pre-initialize the runtime synchronization objects
    24	void
    25	_cgo_preinit_init() {
    26		 runtime_init_wait = CreateEvent(NULL, TRUE, FALSE, NULL);
    27		 if (runtime_init_wait == NULL) {
    28			fprintf(stderr, "runtime: failed to create runtime initialization wait event.\n");
    29			abort();
    30		 }
    31	
    32		 InitializeCriticalSection(&runtime_init_cs);
    33	}
    34	
    35	// Make sure that the preinit sequence has run.
    36	void
    37	_cgo_maybe_run_preinit() {
    38		 if (!InterlockedExchangeAdd(&runtime_init_once_done, 0)) {
    39				if (InterlockedIncrement(&runtime_init_once_gate) == 1) {
    40					 _cgo_preinit_init();
    41					 InterlockedIncrement(&runtime_init_once_done);
    42				} else {
    43					 // Decrement to avoid overflow.
    44					 InterlockedDecrement(&runtime_init_once_gate);
    45					 while(!InterlockedExchangeAdd(&runtime_init_once_done, 0)) {
    46							Sleep(0);
    47					 }
    48				}
    49		 }
    50	}
    51	
    52	void
    53	x_cgo_sys_thread_create(void (*func)(void*), void* arg) {
    54		uintptr_t thandle;
    55	
    56		thandle = _beginthread(func, 0, arg);
    57		if(thandle == -1) {
    58			fprintf(stderr, "runtime: failed to create new OS thread (%d)\n", errno);
    59			abort();
    60		}
    61	}
    62	
    63	int
    64	_cgo_is_runtime_initialized() {
    65		 EnterCriticalSection(&runtime_init_cs);
    66		 int status = runtime_init_done;
    67		 LeaveCriticalSection(&runtime_init_cs);
    68		 return status;
    69	}
    70	
    71	uintptr_t
    72	_cgo_wait_runtime_init_done() {
    73		void (*pfn)(struct context_arg*);
    74	
    75		 _cgo_maybe_run_preinit();
    76		while (!_cgo_is_runtime_initialized()) {
    77				WaitForSingleObject(runtime_init_wait, INFINITE);
    78		}
    79		pfn = _cgo_get_context_function();
    80		if (pfn != nil) {
    81			struct context_arg arg;
    82	
    83			arg.Context = 0;
    84			(*pfn)(&arg);
    85			return arg.Context;
    86		}
    87		return 0;
    88	}
    89	
    90	void
    91	x_cgo_notify_runtime_init_done(void* dummy) {
    92		 _cgo_maybe_run_preinit();
    93	
    94		 EnterCriticalSection(&runtime_init_cs);
    95		runtime_init_done = 1;
    96		 LeaveCriticalSection(&runtime_init_cs);
    97	
    98		 if (!SetEvent(runtime_init_wait)) {
    99			fprintf(stderr, "runtime: failed to signal runtime initialization complete.\n");
   100			abort();
   101		}
   102	}
   103	
   104	// The context function, used when tracing back C calls into Go.
   105	static void (*cgo_context_function)(struct context_arg*);
   106	
   107	// Sets the context function to call to record the traceback context
   108	// when calling a Go function from C code. Called from runtime.SetCgoTraceback.
   109	void x_cgo_set_context_function(void (*context)(struct context_arg*)) {
   110		EnterCriticalSection(&runtime_init_cs);
   111		cgo_context_function = context;
   112		LeaveCriticalSection(&runtime_init_cs);
   113	}
   114	
   115	// Gets the context function.
   116	void (*(_cgo_get_context_function(void)))(struct context_arg*) {
   117		void (*ret)(struct context_arg*);
   118	
   119		EnterCriticalSection(&runtime_init_cs);
   120		ret = cgo_context_function;
   121		LeaveCriticalSection(&runtime_init_cs);
   122		return ret;
   123	}

View as plain text