...

Text file src/runtime/cgo/gcc_libinit_windows.c

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

View as plain text