Blame winpr/libwinpr/synch/init.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * Synchronization Functions
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 * Copyright 2014 Thincast Technologies GmbH
Packit 1fb8d4
 * Copyright 2014 Norbert Federa <norbert.federa@thincast.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/synch.h>
Packit 1fb8d4
#include <winpr/interlocked.h>
Packit 1fb8d4
Packit 1fb8d4
#include "../log.h"
Packit 1fb8d4
#define TAG WINPR_TAG("sync")
Packit 1fb8d4
Packit 1fb8d4
#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600))
Packit 1fb8d4
Packit Service 5a9772
BOOL winpr_InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending,
Packit Service 5a9772
                                   LPVOID* lpContext)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "not implemented");
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
BOOL winpr_InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "not implemented");
Packit 1fb8d4
	return FALSE;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
VOID winpr_InitOnceInitialize(PINIT_ONCE InitOnce)
Packit 1fb8d4
{
Packit 1fb8d4
	WLog_ERR(TAG, "not implemented");
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
BOOL winpr_InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter,
Packit Service 5a9772
                               LPVOID* Context)
Packit 1fb8d4
{
Packit 1fb8d4
	for (;;)
Packit 1fb8d4
	{
Packit 1fb8d4
		switch ((ULONG_PTR)InitOnce->Ptr & 3)
Packit 1fb8d4
		{
Packit 1fb8d4
			case 2:
Packit 1fb8d4
				/* already completed successfully */
Packit 1fb8d4
				return TRUE;
Packit 1fb8d4
Packit 1fb8d4
			case 0:
Packit 1fb8d4
Packit 1fb8d4
				/* first time */
Packit Service 5a9772
				if (InterlockedCompareExchangePointer(&InitOnce->Ptr, (PVOID)1, (PVOID)0) !=
Packit Service 5a9772
				    (PVOID)0)
Packit 1fb8d4
				{
Packit 1fb8d4
					/* some other thread was faster */
Packit 1fb8d4
					break;
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				/* it's our job to call the init function */
Packit 1fb8d4
				if (InitFn(InitOnce, Parameter, Context))
Packit 1fb8d4
				{
Packit 1fb8d4
					/* success */
Packit 1fb8d4
					InitOnce->Ptr = (PVOID)2;
Packit 1fb8d4
					return TRUE;
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				/* the init function returned an error,  reset the status */
Packit 1fb8d4
				InitOnce->Ptr = (PVOID)0;
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
Packit 1fb8d4
			case 1:
Packit 1fb8d4
				/* in progress */
Packit 1fb8d4
				break;
Packit 1fb8d4
Packit 1fb8d4
			default:
Packit 1fb8d4
				WLog_ERR(TAG, "internal error");
Packit 1fb8d4
				return FALSE;
Packit 1fb8d4
		}
Packit 1fb8d4
Packit 1fb8d4
		Sleep(5);
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif