Exemplo n.º 1
0
int ISC_kill(SLONG pid, SLONG signal_number, void *object_hndl)
{
/**************************************
 *
 *	I S C _ k i l l		( W I N _ N T )
 *
 **************************************
 *
 * Functional description
 *	Notify somebody else.
 *
 **************************************/

	// If we're simply trying to poke ourselves, do so directly.
	ISC_signal_init();

	if (pid == process_id)
		return SetEvent(object_hndl) ? 0 : -1;

	HANDLE handle = openEvents->getEvent(pid, signal_number);
	if (!handle)
		return -1;

	return SetEvent(handle) ? 0 : -1;
}
Exemplo n.º 2
0
int ISC_kill(SLONG pid, SLONG signal_number, void *object_hndl)
{
/**************************************
 *
 *	I S C _ k i l l		( W I N _ N T )
 *
 **************************************
 *
 * Functional description
 *	Notify somebody else.
 *
 **************************************/

/* If we're simply trying to poke ourselves, do so directly. */
	ISC_signal_init();

	if (pid == process_id) {
		SetEvent(object_hndl);
		return 0;
	}

	opn_event_t* oldest_opn_event = NULL;
	ULONG oldest_age = ~0;

	opn_event_t* opn_event = opn_events;
	const opn_event_t* const end_opn_event = opn_event + opn_event_count;
	for (; opn_event < end_opn_event; opn_event++) {
		if (opn_event->opn_event_pid == pid &&
			opn_event->opn_event_signal == signal_number)
		{
			break;
		}
		if (opn_event->opn_event_age < oldest_age) {
			oldest_opn_event = opn_event;
			oldest_age = opn_event->opn_event_age;
		}
	}

	if (opn_event >= end_opn_event) {
		HANDLE lhandle = ISC_make_signal(false, false, pid, signal_number);
		if (!lhandle)
			return -1;

		if (opn_event_count < MAX_OPN_EVENTS)
			opn_event_count++;
		else {
			opn_event = oldest_opn_event;
			CloseHandle(opn_event->opn_event_lhandle);
		}

		opn_event->opn_event_pid = pid;
		opn_event->opn_event_signal = signal_number;
		opn_event->opn_event_lhandle = lhandle;
	}

	opn_event->opn_event_age = ++opn_event_clock;

	return SetEvent(opn_event->opn_event_lhandle) ? 0 : -1;
}
Exemplo n.º 3
0
void* ISC_make_signal(bool create_flag, bool manual_reset, int process_idL, int signal_number)
{
/**************************************
 *
 *	I S C _ m a k e _ s i g n a l		( W I N _ N T )
 *
 **************************************
 *
 * Functional description
 *	Create or open a Windows/NT event.
 *	Use the signal number and process id
 *	in naming the object.
 *
 **************************************/
	ISC_signal_init();

	const BOOL man_rst = manual_reset ? TRUE : FALSE;

	if (!signal_number)
		return CreateEvent(NULL, man_rst, FALSE, NULL);

	TEXT event_name[BUFFER_TINY];
	sprintf(event_name, "_firebird_process%u_signal%d", process_idL, signal_number);

	if (!fb_utils::prefix_kernel_object_name(event_name, sizeof(event_name)))
	{
		SetLastError(ERROR_FILENAME_EXCED_RANGE);
		return NULL;
	}

	HANDLE hEvent = OpenEvent(EVENT_ALL_ACCESS, TRUE, event_name);

	if (create_flag) {
		fb_assert(!hEvent);
		hEvent = CreateEvent(ISC_get_security_desc(), man_rst, FALSE, event_name);
	}

	return hEvent;
}
Exemplo n.º 4
0
int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE /*hPrevInst*/, LPSTR lpszArgs, int nWndMode)
{
/**************************************
 *
 *      W i n M a i n
 *
 **************************************
 *
 * Functional description
 *      Run the server with NT named
 *      pipes and/or TCP/IP sockets.
 *
 **************************************/
	hInst = hThisInst;

	// We want server to crash without waiting for feedback from the user
	try
	{
		if (!Config::getBugcheckAbort())
			SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
	}
	catch (Firebird::fatal_exception& e)
	{
		MessageBox(NULL, e.what(), "Firebird server failure",
			MB_OK | MB_ICONHAND | MB_SYSTEMMODAL  | MB_DEFAULT_DESKTOP_ONLY);
		return STARTUP_ERROR; // see /jrd/common.h
	}
	catch (Firebird::status_exception& e)
	{
		TEXT buffer[BUFFER_LARGE];
		const ISC_STATUS* vector = e.value();
		if (! (vector && fb_interpret(buffer, sizeof(buffer), &vector)))
		{
			strcpy(buffer, "Unknown internal failure");
		}

		MessageBox(NULL, buffer, "Firebird server failure",
			MB_OK | MB_ICONHAND | MB_SYSTEMMODAL  | MB_DEFAULT_DESKTOP_ONLY);
		return STARTUP_ERROR; // see /jrd/common.h
	}

#ifdef SUPERSERVER
	server_flag = SRVR_multi_client;
#else
	server_flag = 0;
#endif

#ifdef SUPERSERVER
	SetProcessAffinityMask(GetCurrentProcess(), static_cast<DWORD>(Config::getCpuAffinityMask()));
#endif

	protocol_inet[0] = 0;
	protocol_wnet[0] = 0;

	strcpy(instance, FB_DEFAULT_INSTANCE);

	const HANDLE connection_handle = parse_args(lpszArgs, &server_flag);

#ifdef SUPERSERVER
	// get priority class from the config file
	int priority = Config::getProcessPriorityLevel();

	// override it, if necessary
	if (server_flag & SRVR_high_priority) {
		priority = 1;
	}

	// set priority class
	if (priority > 0) {
		SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
	}
	else if (priority < 0) {
		SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
	}
#endif

	TEXT mutex_name[MAXPATHLEN];
	fb_utils::snprintf(mutex_name, sizeof(mutex_name), SERVER_MUTEX, instance);
	fb_utils::prefix_kernel_object_name(mutex_name, sizeof(mutex_name));
	CreateMutex(ISC_get_security_desc(), FALSE, mutex_name);

	// Initialize the service

	ISC_signal_init();
	Firebird::FpeControl::maskAll();

	int nReturnValue = 0;
	ISC_STATUS_ARRAY status_vector;
	fb_utils::init_status(status_vector);

	fb_shutdown_callback(0, wait_threads, fb_shut_finish, NULL);

	if (connection_handle != INVALID_HANDLE_VALUE)
	{
		rem_port* port = 0;

		if (server_flag & SRVR_inet)
		{
			port = INET_reconnect((SOCKET) connection_handle, status_vector);

			if (port)
			{
				SRVR_multi_thread(port, server_flag);
				port = NULL;
			}
		}
		else if (server_flag & SRVR_wnet)
			port = WNET_reconnect(connection_handle, status_vector);
		else if (server_flag & SRVR_xnet)
			port = XNET_reconnect((ULONG) connection_handle, status_vector);

		if (port) {
			service_connection(port);
		}
		else if (status_vector[1])
			gds__log_status(0, status_vector);

		fb_shutdown(5 * 1000 /*5 seconds*/, fb_shutrsn_no_connection);
	}
	else if (!(server_flag & SRVR_non_service))
	{
		Firebird::string service_name;
		service_name.printf(REMOTE_SERVICE, instance);

		CNTL_init(start_connections_thread, instance);

		const SERVICE_TABLE_ENTRY service_table[] =
		{
			{const_cast<char*>(service_name.c_str()), CNTL_main_thread},
			{NULL, NULL}
		};

		// BRS There is a error in MinGW (3.1.0) headers
		// the parameter of StartServiceCtrlDispatcher is declared const in msvc headers
#if defined(MINGW)
		if (!StartServiceCtrlDispatcher(const_cast<SERVICE_TABLE_ENTRY*>(service_table)))
		{
#else
		if (!StartServiceCtrlDispatcher(service_table))
		{
#endif
			if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) {
				CNTL_shutdown_service("StartServiceCtrlDispatcher failed");
			}
			server_flag |= SRVR_non_service;
		}
	}
	else
	{
		start_connections_thread(0);
		nReturnValue = WINDOW_main(hThisInst, nWndMode, server_flag);
	}

#ifdef DEBUG_GDS_ALLOC
	// In Debug mode - this will report all server-side memory leaks
	// due to remote access

	//gds_alloc_report(0, __FILE__, __LINE__);
	Firebird::PathName name = fb_utils::getPrefix(fb_utils::FB_DIR_LOG, "memdebug.log");
	FILE* file = fopen(name.c_str(), "w+t");
	if (file)
	{
		fprintf(file, "Global memory pool allocated objects\n");
		getDefaultMemoryPool()->print_contents(file);
		fclose(file);
	}
#endif

	return nReturnValue;
}


THREAD_ENTRY_DECLARE process_connection_thread(THREAD_ENTRY_PARAM arg)
{
/**************************************
 *
 *      p r o c e s s _ c o n n e c t i o n _ t h r e a d
 *
 **************************************
 *
 * Functional description
 *
 **************************************/
	ThreadCounter counter;

	service_connection((rem_port*) arg);
	return 0;
}