8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 10:03:03 +01:00

Make remote module thread-safe, remove THREAD_EXIT\THREAD_ENTER from it, refactor server code and some cleanup. To be continued. Please check posix builds.

This commit is contained in:
hvlad 2008-03-11 14:11:32 +00:00
parent 4a1bcd0036
commit 4115317607
12 changed files with 949 additions and 1064 deletions

View File

@ -27,9 +27,6 @@
#include "../remote/remote.h" #include "../remote/remote.h"
#include "gen/iberror.h" #include "gen/iberror.h"
#include "../remote/allr_proto.h" #include "../remote/allr_proto.h"
#include "../remote/remot_proto.h"
#include "../jrd/gds_proto.h"
#include "../common/thd.h"
#include "../common/classes/alloc.h" #include "../common/classes/alloc.h"

View File

@ -77,11 +77,9 @@
#ifdef SUPERSERVER
#ifdef WIN_NT #ifdef WIN_NT
#define FD_SETSIZE 1024 #define FD_SETSIZE 1024
#endif #endif
#endif /* SUPERSERVER */
#ifndef WIN_NT #ifndef WIN_NT
#include <netinet/tcp.h> #include <netinet/tcp.h>
@ -112,7 +110,6 @@ const int INET_RETRY_CALL = 5;
#include "../jrd/os/isc_i_proto.h" #include "../jrd/os/isc_i_proto.h"
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/config/config.h" #include "../common/config/config.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
@ -176,10 +173,6 @@ const int NOTASOCKET = EBADF;
#define FB_SETOPT_FLAGS 0 #define FB_SETOPT_FLAGS 0
#endif #endif
SLONG INET_remote_buffer;
SLONG INET_max_data;
static bool first_time = true;
// //
//#define DEBUG 1 //#define DEBUG 1
// //
@ -244,10 +237,6 @@ typedef struct slct
fd_set slct_fdset; fd_set slct_fdset;
} SLCT; } SLCT;
#ifdef SUPERSERVER
#define DEFER_PORT_CLEANUP
#endif
static int accept_connection(rem_port*, P_CNCT *); static int accept_connection(rem_port*, P_CNCT *);
#ifdef HAVE_SETITIMER #ifdef HAVE_SETITIMER
static void alarm_handler(int); static void alarm_handler(int);
@ -282,9 +271,7 @@ static void copy_p_cnct_repeat_array( p_cnct::p_cnct_repeat* pDest,
static int inet_destroy(XDR *); static int inet_destroy(XDR *);
static void inet_gen_error(rem_port*, ISC_STATUS, ...); static void inet_gen_error(rem_port*, ISC_STATUS, ...);
#if !defined(SUPERSERVER) || defined(EMBEDDED)
static bool_t inet_getbytes(XDR *, SCHAR *, u_int); static bool_t inet_getbytes(XDR *, SCHAR *, u_int);
#endif
static bool_t inet_getlong(XDR *, SLONG *); static bool_t inet_getlong(XDR *, SLONG *);
static u_int inet_getpostn(XDR *); static u_int inet_getpostn(XDR *);
#if !(defined WIN_NT) #if !(defined WIN_NT)
@ -323,14 +310,12 @@ static int select_wait(rem_port*, SLCT *);
static int send_full(rem_port*, PACKET *); static int send_full(rem_port*, PACKET *);
static int send_partial(rem_port*, PACKET *); static int send_partial(rem_port*, PACKET *);
#ifdef DEFER_PORT_CLEANUP
static void unhook_disconnected_ports(rem_port*); static void unhook_disconnected_ports(rem_port*);
#endif
static void unhook_port(rem_port*, rem_port*); static void unhook_port(rem_port*, rem_port*);
static int xdrinet_create(XDR *, rem_port*, UCHAR *, USHORT, enum xdr_op); static int xdrinet_create(XDR *, rem_port*, UCHAR *, USHORT, enum xdr_op);
static bool setNoNagleOption(rem_port*); static bool setNoNagleOption(rem_port*);
static FPTR_VOID tryStopMainThread = 0; static FPTR_VOID tryStopMainThread = 0;
static int shut_preproviders();
@ -338,11 +323,7 @@ static XDR::xdr_ops inet_ops =
{ {
inet_getlong, inet_getlong,
inet_putlong, inet_putlong,
#if !defined(SUPERSERVER) || defined(EMBEDDED)
inet_getbytes, inet_getbytes,
#else
REMOTE_getbytes,
#endif
inet_putbytes, inet_putbytes,
inet_getpostn, inet_getpostn,
inet_setpostn, inet_setpostn,
@ -370,35 +351,22 @@ static XDR::xdr_ops inet_ops =
#endif #endif
#endif #endif
static SLCT INET_select = { 0, 0, 0 };
static int INET_max_clients;
#ifdef WIN_NT
static bool INET_initialized = false;
static WSADATA INET_wsadata;
#endif
#ifdef WIN_NT #ifdef WIN_NT
#define INTERRUPT_ERROR(x) (SYSCALL_INTERRUPTED(x) || (x) == WSAEINTR) #define INTERRUPT_ERROR(x) (SYSCALL_INTERRUPTED(x) || (x) == WSAEINTR)
#else #else
#define INTERRUPT_ERROR(x) (SYSCALL_INTERRUPTED(x)) #define INTERRUPT_ERROR(x) (SYSCALL_INTERRUPTED(x))
#endif #endif
SLONG INET_remote_buffer;
static bool INET_initialized = false;
static bool INET_shutting_down = false;
static SLCT INET_select = { 0, 0, 0 };
static int INET_max_clients;
static Firebird::GlobalPtr<Firebird::Mutex> port_mutex; static Firebird::GlobalPtr<Firebird::Mutex> port_mutex;
inline void START_PORT_CRITICAL()
{
THREAD_EXIT();
port_mutex->enter();
THREAD_ENTER();
}
inline void STOP_PORT_CRITICAL()
{
port_mutex->leave();
}
rem_port* INET_analyze(Firebird::PathName& file_name, rem_port* INET_analyze(Firebird::PathName& file_name,
ISC_STATUS* status_vector, ISC_STATUS* status_vector,
@ -700,8 +668,6 @@ rem_port* INET_connect(const TEXT* name,
host_addr = get_bind_address(); host_addr = get_bind_address();
} }
THREAD_EXIT();
const struct servent* service = getservbyname(protocol.c_str(), "tcp"); const struct servent* service = getservbyname(protocol.c_str(), "tcp");
#ifdef WIN_NT #ifdef WIN_NT
/* On Windows NT/9x, getservbyname can only accomodate /* On Windows NT/9x, getservbyname can only accomodate
@ -719,7 +685,6 @@ rem_port* INET_connect(const TEXT* name,
} }
} }
#endif /* WIN_NT */ #endif /* WIN_NT */
THREAD_ENTER();
/* Modification by luz (slightly modified by FSG) /* Modification by luz (slightly modified by FSG)
instead of failing here, try applying hard-wired instead of failing here, try applying hard-wired
@ -801,11 +766,10 @@ rem_port* INET_connect(const TEXT* name,
// If host has two addresses and the first one failed, // If host has two addresses and the first one failed,
// but the second one succeeded - no need to worry // but the second one succeeded - no need to worry
THREAD_EXIT();
n = connect((SOCKET) port->port_handle, n = connect((SOCKET) port->port_handle,
(struct sockaddr *) &address, sizeof(address)); (struct sockaddr *) &address, sizeof(address));
inetErrNo = INET_ERRNO; inetErrNo = INET_ERRNO;
THREAD_ENTER();
if (n != -1 && send_full(port, packet)) if (n != -1 && send_full(port, packet))
return port; return port;
} }
@ -898,18 +862,17 @@ rem_port* INET_connect(const TEXT* name,
port->port_dummy_packet_interval = 0; port->port_dummy_packet_interval = 0;
port->port_dummy_timeout = 0; port->port_dummy_timeout = 0;
port->port_server_flags |= (SRVR_server | SRVR_multi_client); port->port_server_flags |= (SRVR_server | SRVR_multi_client);
gds__register_cleanup(exit_handler, (void *) port); gds__register_cleanup(exit_handler, (void *) port);
return port; return port;
} }
while (true) { while (true) {
THREAD_EXIT();
socklen_t l = sizeof(address); socklen_t l = sizeof(address);
SOCKET s = accept((SOCKET) port->port_handle, SOCKET s = accept((SOCKET) port->port_handle,
(struct sockaddr *) &address, &l); (struct sockaddr *) &address, &l);
const int inetErrNo = INET_ERRNO; const int inetErrNo = INET_ERRNO;
if (s == INVALID_SOCKET) { if (s == INVALID_SOCKET) {
THREAD_ENTER();
inet_error(port, "accept", isc_net_connect_err, inetErrNo); inet_error(port, "accept", isc_net_connect_err, inetErrNo);
disconnect(port); disconnect(port);
return NULL; return NULL;
@ -920,13 +883,11 @@ rem_port* INET_connect(const TEXT* name,
if ((flag & SRVR_debug) || !fork()) if ((flag & SRVR_debug) || !fork())
#endif #endif
{ {
THREAD_ENTER();
SOCLOSE((SOCKET) port->port_handle); SOCLOSE((SOCKET) port->port_handle);
port->port_handle = (HANDLE) s; port->port_handle = (HANDLE) s;
port->port_server_flags |= SRVR_server; port->port_server_flags |= SRVR_server;
return port; return port;
} }
THREAD_ENTER();
SOCLOSE(s); SOCLOSE(s);
} }
} }
@ -1016,6 +977,7 @@ void INET_set_clients( int count)
INET_max_clients = (count && count < MAXCLIENTS) ? count : MAXCLIENTS; INET_max_clients = (count && count < MAXCLIENTS) ? count : MAXCLIENTS;
} }
static int accept_connection(rem_port* port, static int accept_connection(rem_port* port,
P_CNCT* cnct) P_CNCT* cnct)
{ {
@ -1215,34 +1177,32 @@ static rem_port* alloc_port( rem_port* parent)
TEXT buffer[BUFFER_SMALL]; TEXT buffer[BUFFER_SMALL];
if (!INET_initialized)
{
#ifdef WIN_NT #ifdef WIN_NT
if (!INET_initialized) { static WSADATA wsadata;
const WORD version = MAKEWORD(2, 0); const WORD version = MAKEWORD(2, 0);
if (WSAStartup(version, &INET_wsadata)) { const int wsaError = WSAStartup(version, &wsadata);
if (wsaError) {
if (parent) if (parent)
inet_error(parent, "WSAStartup", isc_net_init_error, INET_ERRNO); inet_error(parent, "WSAStartup", isc_net_init_error, wsaError);
else { else {
SNPRINTF(buffer, FB_NELEM(buffer), SNPRINTF(buffer, FB_NELEM(buffer),
"INET/alloc_port: WSAStartup failed, error code = %d", "INET/alloc_port: WSAStartup failed, error code = %d",
INET_ERRNO); wsaError);
gds__log(buffer, 0); gds__log(buffer, 0);
} }
return NULL; return NULL;
} }
gds__register_cleanup(exit_handler, 0); gds__register_cleanup(exit_handler, 0);
INET_initialized = true;
}
#endif #endif
if (first_time)
{
INET_remote_buffer = Config::getTcpRemoteBufferSize(); INET_remote_buffer = Config::getTcpRemoteBufferSize();
if (INET_remote_buffer < MAX_DATA_LW || if (INET_remote_buffer < MAX_DATA_LW ||
INET_remote_buffer > MAX_DATA_HW) INET_remote_buffer > MAX_DATA_HW)
{ {
INET_remote_buffer = DEF_MAX_DATA; INET_remote_buffer = DEF_MAX_DATA;
} }
INET_max_data = INET_remote_buffer;
#ifdef DEBUG #ifdef DEBUG
{ {
char msg[BUFFER_SMALL]; char msg[BUFFER_SMALL];
@ -1251,7 +1211,10 @@ static rem_port* alloc_port( rem_port* parent)
gds__log(msg, 0); gds__log(msg, 0);
} }
#endif #endif
first_time = false;
fb_shutdown_callback(0, shut_preproviders, fb_shut_preproviders);
INET_initialized = true;
} }
rem_port* port = (rem_port*) ALLR_block(type_port, INET_remote_buffer * 2); rem_port* port = (rem_port*) ALLR_block(type_port, INET_remote_buffer * 2);
port->port_type = port_inet; port->port_type = port_inet;
@ -1264,8 +1227,10 @@ static rem_port* alloc_port( rem_port* parent)
SNPRINTF(buffer, FB_NELEM(buffer), "tcp (%s)", port->port_host->str_data); SNPRINTF(buffer, FB_NELEM(buffer), "tcp (%s)", port->port_host->str_data);
port->port_version = REMOTE_make_string(buffer); port->port_version = REMOTE_make_string(buffer);
START_PORT_CRITICAL(); if (parent && !(parent->port_server_flags & SRVR_thread_per_port))
if (parent && !(parent->port_server_flags & SRVR_thread_per_port)) { {
Firebird::MutexLockGuard guard(port_mutex);
port->port_parent = parent; port->port_parent = parent;
port->port_next = parent->port_clients; port->port_next = parent->port_clients;
parent->port_clients = parent->port_next = port; parent->port_clients = parent->port_next = port;
@ -1273,7 +1238,6 @@ static rem_port* alloc_port( rem_port* parent)
port->port_server = parent->port_server; port->port_server = parent->port_server;
port->port_server_flags = parent->port_server_flags; port->port_server_flags = parent->port_server_flags;
} }
STOP_PORT_CRITICAL();
port->port_accept = accept_connection; port->port_accept = accept_connection;
port->port_disconnect = disconnect; port->port_disconnect = disconnect;
@ -1295,11 +1259,15 @@ static rem_port* alloc_port( rem_port* parent)
0, 0,
XDR_DECODE); XDR_DECODE);
#ifdef SUPERSERVER #ifdef REM_SERVER
port->port_queue = FB_NEW(*getDefaultMemoryPool()) port->port_queue = FB_NEW(*getDefaultMemoryPool())
Firebird::ObjectsArray< Firebird::Array< char > >(*getDefaultMemoryPool()); Firebird::ObjectsArray< Firebird::Array< char > >(*getDefaultMemoryPool());
port->port_qoffset = 0; port->port_qoffset = 0;
port->port_que_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_que_sync->addRef();
#endif #endif
port->port_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_sync->addRef();
return port; return port;
} }
@ -1325,10 +1293,8 @@ static rem_port* aux_connect(rem_port* port, PACKET* packet, t_event_ast ast)
if (port->port_server_flags) { if (port->port_server_flags) {
THREAD_EXIT();
SOCKET n = accept(port->port_channel, (struct sockaddr *) &address, &l); SOCKET n = accept(port->port_channel, (struct sockaddr *) &address, &l);
const int inetErrNo = INET_ERRNO; const int inetErrNo = INET_ERRNO;
THREAD_ENTER();
if (n == INVALID_SOCKET) { if (n == INVALID_SOCKET) {
inet_error(port, "accept", isc_net_event_connect_err, inetErrNo); inet_error(port, "accept", isc_net_event_connect_err, inetErrNo);
@ -1378,10 +1344,8 @@ static rem_port* aux_connect(rem_port* port, PACKET* packet, t_event_ast ast)
address.sin_family = AF_INET; address.sin_family = AF_INET;
address.sin_port = ((struct sockaddr_in *)(response->p_resp_data.cstr_address))->sin_port; address.sin_port = ((struct sockaddr_in *)(response->p_resp_data.cstr_address))->sin_port;
THREAD_EXIT();
status = connect(n, (struct sockaddr *) &address, sizeof(address)); status = connect(n, (struct sockaddr *) &address, sizeof(address));
const int inetErrNo = INET_ERRNO; const int inetErrNo = INET_ERRNO;
THREAD_ENTER();
if (status < 0) { if (status < 0) {
inet_error(port, "connect", isc_net_event_connect_err, inetErrNo); inet_error(port, "connect", isc_net_event_connect_err, inetErrNo);
@ -1676,21 +1640,20 @@ static void disconnect( rem_port* port)
/* If this is a sub-port, unlink it from it's parent */ /* If this is a sub-port, unlink it from it's parent */
#ifdef DEFER_PORT_CLEANUP
bool defer_cleanup = false; bool defer_cleanup = false;
port->port_state = state_disconnected; port->port_state = state_disconnected;
#endif
rem_port* parent = port->port_parent; rem_port* parent = port->port_parent;
if (parent != NULL) { if (parent != NULL) {
if (port->port_async) { if (port->port_async) {
disconnect(port->port_async); disconnect(port->port_async);
port->port_async = NULL; port->port_async = NULL;
} }
#ifdef DEFER_PORT_CLEANUP
defer_cleanup = true; defer_cleanup = (port->port_server_flags & SRVR_multi_client);
#else if (!defer_cleanup) {
unhook_port(port, parent); unhook_port(port, parent);
#endif }
} }
else if (port->port_async) { else if (port->port_async) {
port->port_async->port_flags |= PORT_disconnect; port->port_async->port_flags |= PORT_disconnect;
@ -1702,10 +1665,9 @@ static void disconnect( rem_port* port)
gds__unregister_cleanup(exit_handler, (void *) port); gds__unregister_cleanup(exit_handler, (void *) port);
#ifdef DEFER_PORT_CLEANUP if (!defer_cleanup) {
if (!defer_cleanup)
#endif
cleanup_port(port); cleanup_port(port);
}
#ifdef DEBUG #ifdef DEBUG
if (INET_trace & TRACE_summary) { if (INET_trace & TRACE_summary) {
@ -1765,9 +1727,11 @@ static void cleanup_port( rem_port* port)
ALLR_free(port->port_packet_vector); ALLR_free(port->port_packet_vector);
#endif #endif
#ifdef SUPERSERVER #ifdef REM_SERVER
delete port->port_queue; delete port->port_queue;
port->port_que_sync->release();
#endif #endif
port->port_sync->release();
#ifdef TRUSTED_AUTH #ifdef TRUSTED_AUTH
delete port->port_trusted_auth; delete port->port_trusted_auth;
@ -1794,14 +1758,18 @@ static void exit_handler( void *arg)
rem_port* main_port = (rem_port*) arg; rem_port* main_port = (rem_port*) arg;
#ifdef WIN_NT #ifdef WIN_NT
if (!main_port) { if (!main_port)
{
SleepEx(0, FALSE); // let select in other thread(s) shutdown gracefully SleepEx(0, FALSE); // let select in other thread(s) shutdown gracefully
WSACleanup(); WSACleanup();
return; return;
} }
#endif #endif
for (rem_port* port = main_port; port; port = port->port_next) { for (rem_port* port = main_port; port; port = port->port_next)
if (port->port_state != state_broken)
{
port->port_state = state_broken;
shutdown((int) port->port_handle, 2); shutdown((int) port->port_handle, 2);
SOCLOSE((SOCKET) port->port_handle); SOCLOSE((SOCKET) port->port_handle);
} }
@ -1913,8 +1881,6 @@ static in_addr get_host_address(const Firebird::string& name,
* *
**************************************/ **************************************/
THREAD_EXIT();
host_addr_arr[0].s_addr = inet_addr(name.c_str()); host_addr_arr[0].s_addr = inet_addr(name.c_str());
host_addr_arr[1].s_addr = 0L; host_addr_arr[1].s_addr = 0L;
@ -1956,8 +1922,6 @@ static in_addr get_host_address(const Firebird::string& name,
} }
} }
THREAD_ENTER();
return host_addr_arr[0]; return host_addr_arr[0];
} }
@ -2125,13 +2089,6 @@ static rem_port* receive( rem_port* main_port, PACKET * packet)
* *
**************************************/ **************************************/
#ifndef SUPERSERVER
/* If this isn't a multi-client server, just do the operation and get it
over with */
if (!(main_port->port_server_flags & SRVR_multi_client))
#endif //SUPERSERVER
{
/* loop as long as we are receiving dummy packets, just /* loop as long as we are receiving dummy packets, just
throwing them away--note that if we are a server we won't throwing them away--note that if we are a server we won't
be receiving them, but it is better to check for them at be receiving them, but it is better to check for them at
@ -2166,63 +2123,6 @@ static rem_port* receive( rem_port* main_port, PACKET * packet)
while (packet->p_operation == op_dummy); while (packet->p_operation == op_dummy);
return main_port; return main_port;
}
#ifndef SUPERSERVER
/* Multi-client server multiplexes all known ports for incoming packets. */
for (;;) {
rem_port* port = select_port(main_port, &INET_select);
if (port == main_port) {
if (port = select_accept(main_port))
return port;
continue;
}
if (port) {
if (port->port_dummy_timeout < 0) {
port->port_dummy_timeout = port->port_dummy_packet_interval;
if (port->port_flags & PORT_async ||
port->port_protocol < PROTOCOL_VERSION8)
{
continue;
}
packet->p_operation = op_dummy;
return port;
}
/* We've got data -- lap it up and use it */
if (!xdr_protocol(&port->port_receive, packet))
packet->p_operation = op_exit;
#ifdef DEBUG
{
static ULONG op_rec_count = 0;
op_rec_count++;
if (INET_trace & TRACE_operations) {
fprintf(stdout, "%05lu: OP Recd %5lu opcode %d\n",
inet_debug_timer(),
op_rec_count, packet->p_operation);
fflush(stdout);
}
}
#endif
/* Make sure that there are no more messages in this port before blocking
ourselves in select_wait. If there are more messages then set the flag
corresponding to this port which was cleared in select_port routine.
*/
if (port->port_receive.x_handy) {
FD_SET((SLONG) port->port_handle, &INET_select.slct_fdset);
++INET_select.slct_count;
}
if (packet->p_operation == op_dummy)
continue;
return port;
}
if (!select_wait(main_port, &INET_select))
return NULL;
}
#endif //SUPERSERVER
} }
static rem_port* select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize, SSHORT* length) static rem_port* select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize, SSHORT* length)
@ -2247,7 +2147,17 @@ static rem_port* select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize
rem_port* port = select_port(main_port, &INET_select); rem_port* port = select_port(main_port, &INET_select);
if (port == main_port) if (port == main_port)
{ {
if (port = select_accept(main_port)) if (INET_shutting_down)
{
if (main_port->port_state != state_broken)
{
main_port->port_state = state_broken;
SOCKET s = (SOCKET) main_port->port_handle;
shutdown(s, 2);
SOCLOSE(s);
}
}
else if (port = select_accept(main_port))
{ {
if (!packet_receive(port, buffer, bufsize, length)) if (!packet_receive(port, buffer, bufsize, length))
{ {
@ -2271,6 +2181,9 @@ static rem_port* select_multi(rem_port* main_port, UCHAR* buffer, SSHORT bufsize
if (!packet_receive(port, buffer, bufsize, length)) if (!packet_receive(port, buffer, bufsize, length))
{ {
if (port->port_flags & PORT_disconnect) {
continue;
}
*length = 0; *length = 0;
} }
return port; return port;
@ -2292,9 +2205,6 @@ static rem_port* select_accept( rem_port* main_port)
* *
* Functional description * Functional description
* Accept a new connection request. * Accept a new connection request.
* If client load is exceeded then
* handoff connection responsibility
* to a fresh server.
* *
**************************************/ **************************************/
struct sockaddr_in address; struct sockaddr_in address;
@ -2314,22 +2224,7 @@ static rem_port* select_accept( rem_port* main_port)
setsockopt((SOCKET) port->port_handle, SOL_SOCKET, SO_KEEPALIVE, setsockopt((SOCKET) port->port_handle, SOL_SOCKET, SO_KEEPALIVE,
(SCHAR*) &optval, sizeof(optval)); (SCHAR*) &optval, sizeof(optval));
#if !(defined SUPERSERVER || defined WIN_NT) port->port_flags |= PORT_server;
int n;
for (n = 0, port = main_port->port_clients; port;
n++, port = port->port_next);
if (n >= INET_max_clients) {
main_port->port_state = state_closed;
SOCLOSE((int) main_port->port_handle);
TEXT msg[BUFFER_SMALL];
SNPRINTF(msg, FB_NELEM(msg),
"INET/select_accept: exec new server at client limit: %d", n);
gds__log(msg, 0);
setreuid(0, 0);
kill(getppid(), SIGUSR1);
}
#endif
if (main_port->port_server_flags & SRVR_thread_per_port) { if (main_port->port_server_flags & SRVR_thread_per_port) {
port->port_server_flags = port->port_server_flags =
@ -2357,59 +2252,32 @@ static rem_port* select_port( rem_port* main_port, SLCT * selct)
* NULL if none are active. * NULL if none are active.
* *
**************************************/ **************************************/
#ifdef WIN_NT
/* NT's socket handles are addresses */ Firebird::MutexLockGuard guard(port_mutex);
/* TMN: No, they are "black-box" handles. */
START_PORT_CRITICAL();
#ifdef DEFER_PORT_CLEANUP
unhook_disconnected_ports(main_port); unhook_disconnected_ports(main_port);
#endif for (rem_port* port = main_port; port; port = port->port_next)
for (rem_port* port = main_port; port; port = port->port_next) {
if (FD_ISSET(port->port_handle, &selct->slct_fdset))
{ {
port->port_dummy_timeout = port->port_dummy_packet_interval; #ifdef WIN_NT
const SOCKET n = (SOCKET) port->port_handle;
#pragma FB_COMPILER_MESSAGE("TODO: Make porthandle a SOCKET on Win32") if (FD_ISSET(n, &selct->slct_fdset))
#else
FD_CLR((SOCKET) port->port_handle, &selct->slct_fdset);
--selct->slct_count;
STOP_PORT_CRITICAL();
return port;
}
if (port->port_dummy_timeout < 0) {
STOP_PORT_CRITICAL();
return port;
}
}
STOP_PORT_CRITICAL();
#else // !defined(WIN_NT)
START_PORT_CRITICAL();
#ifdef DEFER_PORT_CLEANUP
unhook_disconnected_ports(main_port);
#endif
for (rem_port* port = main_port; port; port = port->port_next) {
const int n = (int) port->port_handle; const int n = (int) port->port_handle;
if (n < 0 || n >= FD_SETSIZE) { if (n < 0 || n >= FD_SETSIZE) {
STOP_PORT_CRITICAL();
return port; return port;
} }
if (n < selct->slct_width && FD_ISSET(n, &selct->slct_fdset)) { if (n < selct->slct_width && FD_ISSET(n, &selct->slct_fdset))
#endif
{
port->port_dummy_timeout = port->port_dummy_packet_interval; port->port_dummy_timeout = port->port_dummy_packet_interval;
FD_CLR(n, &selct->slct_fdset); FD_CLR(n, &selct->slct_fdset);
--selct->slct_count; --selct->slct_count;
STOP_PORT_CRITICAL();
return port; return port;
} }
if (port->port_dummy_timeout < 0) { if (port->port_dummy_timeout < 0) {
STOP_PORT_CRITICAL();
return port; return port;
} }
} }
STOP_PORT_CRITICAL();
#endif
return NULL; return NULL;
} }
@ -2453,10 +2321,9 @@ static int select_wait( rem_port* main_port, SLCT * selct)
selct->slct_time = (SLONG) time(NULL); selct->slct_time = (SLONG) time(NULL);
} }
START_PORT_CRITICAL(); { // port_mutex scope
#ifdef DEFER_PORT_CLEANUP Firebird::MutexLockGuard guard(port_mutex);
unhook_disconnected_ports(main_port); unhook_disconnected_ports(main_port);
#endif
for (rem_port* port = main_port; port; port = port->port_next) for (rem_port* port = main_port; port; port = port->port_next)
{ {
if (port->port_state == state_pending) if (port->port_state == state_pending)
@ -2504,36 +2371,35 @@ static int select_wait( rem_port* main_port, SLCT * selct)
selct->slct_width = (int) port->port_handle + 1; selct->slct_width = (int) port->port_handle + 1;
#endif #endif
} }
STOP_PORT_CRITICAL();
return true; return true;
} }
} }
} }
// if process is shuting down - don't listen on main port
if (!INET_shutting_down || port != main_port)
{
FD_SET((SLONG) port->port_handle, &selct->slct_fdset); FD_SET((SLONG) port->port_handle, &selct->slct_fdset);
#ifdef WIN_NT #ifdef WIN_NT
++selct->slct_width; ++selct->slct_width;
#else #else
selct->slct_width = selct->slct_width = MAX(selct->slct_width, (int) port->port_handle + 1);
MAX(selct->slct_width, (int) port->port_handle); #endif
#endif
found = true; found = true;
} }
} }
}
checkPorts = false; checkPorts = false;
STOP_PORT_CRITICAL(); } // port_mutex scope
if (!found) if (!found)
{ {
gds__log("INET/select_wait: client rundown complete, server exiting", if (!INET_shutting_down) {
0); gds__log("INET/select_wait: client rundown complete, server exiting", 0);
}
return FALSE; return FALSE;
} }
THREAD_EXIT();
++selct->slct_width;
for (;;) for (;;)
{ {
// Before waiting for incoming packet, check for server shutdown // Before waiting for incoming packet, check for server shutdown
@ -2555,6 +2421,11 @@ static int select_wait( rem_port* main_port, SLCT * selct)
NULL, NULL, &timeout); NULL, NULL, &timeout);
#endif #endif
const int inetErrNo = INET_ERRNO; const int inetErrNo = INET_ERRNO;
//if (INET_shutting_down) {
// return FALSE;
//}
if (selct->slct_count != -1) if (selct->slct_count != -1)
{ {
/* if selct->slct_count is zero it means that we timed out of /* if selct->slct_count is zero it means that we timed out of
@ -2573,7 +2444,6 @@ static int select_wait( rem_port* main_port, SLCT * selct)
#endif #endif
} }
} }
THREAD_ENTER();
return TRUE; return TRUE;
} }
if (INTERRUPT_ERROR(inetErrNo)) if (INTERRUPT_ERROR(inetErrNo))
@ -2584,15 +2454,12 @@ static int select_wait( rem_port* main_port, SLCT * selct)
break; break;
} }
THREAD_ENTER();
SNPRINTF(msg, FB_NELEM(msg), SNPRINTF(msg, FB_NELEM(msg),
"INET/select_wait: select failed, errno = %d", "INET/select_wait: select failed, errno = %d",
inetErrNo); inetErrNo);
gds__log(msg, 0); gds__log(msg, 0);
return FALSE; return FALSE;
} // for (;;) } // for (;;)
THREAD_ENTER();
} }
} }
@ -2745,7 +2612,7 @@ static void inet_gen_error( rem_port* port, ISC_STATUS status, ...)
} }
} }
#if !defined(SUPERSERVER) || defined(EMBEDDED)
static bool_t inet_getbytes( XDR * xdrs, SCHAR * buff, u_int count) static bool_t inet_getbytes( XDR * xdrs, SCHAR * buff, u_int count)
{ {
/************************************** /**************************************
@ -2758,6 +2625,13 @@ static bool_t inet_getbytes( XDR * xdrs, SCHAR * buff, u_int count)
* Get a bunch of bytes from a memory stream if it fits. * Get a bunch of bytes from a memory stream if it fits.
* *
**************************************/ **************************************/
#ifdef REM_SERVER
rem_port* port = (rem_port*) xdrs->x_public;
if (port->port_flags & PORT_server) {
return REMOTE_getbytes(xdrs, buff, count);
}
#endif
SLONG bytecount = count; SLONG bytecount = count;
/* Use memcpy to optimize bulk transfers. */ /* Use memcpy to optimize bulk transfers. */
@ -2808,7 +2682,7 @@ static bool_t inet_getbytes( XDR * xdrs, SCHAR * buff, u_int count)
return TRUE; return TRUE;
} }
#endif //#endif
static bool_t inet_getlong( XDR * xdrs, SLONG * lp) static bool_t inet_getlong( XDR * xdrs, SLONG * lp)
{ {
@ -3167,7 +3041,7 @@ static bool_t inet_write( XDR * xdrs, bool_t end_flag)
//p = xdrs->x_base; redundant //p = xdrs->x_base; redundant
while (length) { while (length) {
const SSHORT l = (SSHORT) MIN(length, INET_max_data); const SSHORT l = (SSHORT) MIN(length, INET_remote_buffer);
length -= l; length -= l;
if (!packet_send(port, p, (SSHORT) ((length) ? -l : l))) if (!packet_send(port, p, (SSHORT) ((length) ? -l : l)))
return FALSE; return FALSE;
@ -3273,6 +3147,11 @@ static int packet_receive(
* a duplicate message, just ignore it. * a duplicate message, just ignore it.
* *
**************************************/ **************************************/
if (port->port_flags & PORT_disconnect) {
return FALSE;
}
/* set the time interval for sending dummy packets to the client */ /* set the time interval for sending dummy packets to the client */
timeval timeout; timeval timeout;
@ -3321,21 +3200,18 @@ static int packet_receive(
/* Don't send op_dummy packets on aux port; the server won't /* Don't send op_dummy packets on aux port; the server won't
read them because it only writes to aux ports. */ read them because it only writes to aux ports. */
if (!(port->port_flags & PORT_async)) if ( !(port->port_flags & PORT_async) )
{ {
fd_set slct_fdset; fd_set slct_fdset;
FD_ZERO(&slct_fdset); FD_ZERO(&slct_fdset);
FD_SET(ph, &slct_fdset); FD_SET(ph, &slct_fdset);
THREAD_EXIT();
int slct_count; int slct_count;
for (;;) { for (;;) {
#if (defined WIN_NT) #if (defined WIN_NT)
slct_count = select(FD_SETSIZE, &slct_fdset, slct_count = select(FD_SETSIZE, &slct_fdset, NULL, NULL, time_ptr);
NULL, NULL, time_ptr);
#else #else
slct_count = slct_count = select((SOCKET) port->port_handle + 1, &slct_fdset,
select((SOCKET) port->port_handle + 1, &slct_fdset,
NULL, NULL, time_ptr); NULL, NULL, time_ptr);
#endif #endif
inetErrNo = INET_ERRNO; inetErrNo = INET_ERRNO;
@ -3348,12 +3224,12 @@ static int packet_receive(
break; break;
} }
} }
THREAD_ENTER();
if (slct_count == -1) if (slct_count == -1)
{ {
inet_error(port, "select in packet_receive", if (!(port->port_flags & PORT_disconnect)) {
isc_net_read_err, inetErrNo); inet_error(port, "select in packet_receive", isc_net_read_err, inetErrNo);
}
return FALSE; return FALSE;
} }
@ -3381,16 +3257,17 @@ static int packet_receive(
} }
} }
THREAD_EXIT(); n = recv((SOCKET) port->port_handle, reinterpret_cast<char*>(buffer), buffer_length, 0);
n =
recv((SOCKET) port->port_handle,
reinterpret_cast<char*>(buffer), buffer_length, 0);
inetErrNo = INET_ERRNO; inetErrNo = INET_ERRNO;
THREAD_ENTER();
if (n != -1 || !INTERRUPT_ERROR(inetErrNo)) if (n != -1 || !INTERRUPT_ERROR(inetErrNo))
break; break;
} }
if ((n <= 0) && (port->port_flags & PORT_disconnect)) {
return FALSE;
}
if (n == -1) { if (n == -1) {
inet_error(port, "read", isc_net_read_err, inetErrNo); inet_error(port, "read", isc_net_read_err, inetErrNo);
return FALSE; return FALSE;
@ -3440,7 +3317,6 @@ static bool_t packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_le
SSHORT length = buffer_length; SSHORT length = buffer_length;
while (length) { while (length) {
THREAD_EXIT();
#ifdef DEBUG #ifdef DEBUG
if (INET_trace & TRACE_operations) { if (INET_trace & TRACE_operations) {
fprintf(stdout, "Before Send\n"); fprintf(stdout, "Before Send\n");
@ -3455,7 +3331,6 @@ static bool_t packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_le
fflush(stdout); fflush(stdout);
} }
#endif #endif
THREAD_ENTER();
if (n == length) { if (n == length) {
break; break;
} }
@ -3481,7 +3356,6 @@ static bool_t packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_le
if ((port->port_flags & PORT_async) && !(port->port_flags & PORT_no_oob)) if ((port->port_flags & PORT_async) && !(port->port_flags & PORT_no_oob))
{ {
THREAD_EXIT();
int count = 0; int count = 0;
SSHORT n; SSHORT n;
int inetErrNo = 0; int inetErrNo = 0;
@ -3536,7 +3410,6 @@ static bool_t packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_le
} }
#endif /* HAVE_SETITIMER */ #endif /* HAVE_SETITIMER */
THREAD_ENTER();
if (n == -1) { if (n == -1) {
inet_error(port, "send/oob", isc_net_write_err, inetErrNo); inet_error(port, "send/oob", isc_net_write_err, inetErrNo);
return FALSE; return FALSE;
@ -3572,8 +3445,7 @@ static void unhook_port( rem_port* port, rem_port* parent)
* *
* Functional description * Functional description
* Disconnect a port from its parent * Disconnect a port from its parent
* This must be done under * This must be done under port_mutex control.
* START_PORT_CRITICAL/STOP_PORT_CRITICAL control.
* *
**************************************/ **************************************/
@ -3588,7 +3460,6 @@ static void unhook_port( rem_port* port, rem_port* parent)
} }
} }
#ifdef DEFER_PORT_CLEANUP
static void unhook_disconnected_ports(rem_port* main_port) static void unhook_disconnected_ports(rem_port* main_port)
{ {
/************************************** /**************************************
@ -3600,8 +3471,7 @@ static void unhook_disconnected_ports(rem_port* main_port)
* Functional description * Functional description
* Go through a list of ports and get rid of any * Go through a list of ports and get rid of any
* that are disconnected. Note that this must be * that are disconnected. Note that this must be
* done under START_PORT_CRITICAL/STOP_PORT_CRITICAL * done port_mutex control.
* control.
* *
**************************************/ **************************************/
@ -3610,16 +3480,20 @@ static void unhook_disconnected_ports(rem_port* main_port)
while (more) { while (more) {
more = false; more = false;
for (rem_port* port = main_port; port; port = port->port_next) { for (rem_port* port = main_port; port; port = port->port_next) {
if (port->port_sync->tryEnter()) {
if (port->port_state == state_disconnected) { if (port->port_state == state_disconnected) {
more = true; more = true;
unhook_port(port, port->port_parent); unhook_port(port, port->port_parent);
cleanup_port(port); cleanup_port(port);
break; break;
} }
else {
port->port_sync->leave();
}
}
} }
} }
} }
#endif
static bool setNoNagleOption(rem_port* port) static bool setNoNagleOption(rem_port* port)
{ {
@ -3663,3 +3537,9 @@ void setStopMainThread(FPTR_VOID func)
**************************************/ **************************************/
tryStopMainThread = func; tryStopMainThread = func;
} }
static int shut_preproviders()
{
INET_shutting_down = true;
return 0;
}

View File

@ -61,7 +61,6 @@
#include "../jrd/isc_f_proto.h" #include "../jrd/isc_f_proto.h"
#include "../jrd/sdl_proto.h" #include "../jrd/sdl_proto.h"
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "../common/config/config.h" #include "../common/config/config.h"
#include "../common/utils_proto.h" #include "../common/utils_proto.h"
@ -291,8 +290,6 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
* Connect to an old, grungy database, corrupted by user data. * Connect to an old, grungy database, corrupted by user data.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS* v = user_status; ISC_STATUS* v = user_status;
*v++ = isc_arg_gds; *v++ = isc_arg_gds;
@ -329,6 +326,7 @@ ISC_STATUS GDS_ATTACH_DATABASE(ISC_STATUS* user_status,
return user_status[1]; return user_status[1];
} }
Firebird::RefMutexGuard portGuard(*port->port_sync); // hvlad ???
rdb = port->port_context; rdb = port->port_context;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -374,12 +372,13 @@ ISC_STATUS GDS_BLOB_INFO(ISC_STATUS* user_status,
* Provide information on blob object. * Provide information on blob object.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RBL blob = *blob_handle; RBL blob = *blob_handle;
CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle); CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle);
RDB rdb = blob->rbl_rdb; RDB rdb = blob->rbl_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -410,8 +409,6 @@ ISC_STATUS GDS_CANCEL_BLOB(ISC_STATUS * user_status, RBL * blob_handle)
* Abort a partially completed blob. * Abort a partially completed blob.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RBL blob = *blob_handle; RBL blob = *blob_handle;
if (!blob) { if (!blob) {
if (user_status) { if (user_status) {
@ -423,8 +420,11 @@ ISC_STATUS GDS_CANCEL_BLOB(ISC_STATUS * user_status, RBL * blob_handle)
} }
CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle); CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle);
RDB rdb = blob->rbl_rdb; RDB rdb = blob->rbl_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -457,13 +457,12 @@ ISC_STATUS GDS_CANCEL_EVENTS(ISC_STATUS * user_status, RDB * handle, SLONG * id)
* Cancel an outstanding event. * Cancel an outstanding event.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RDB rdb = *handle; RDB rdb = *handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port;
try try
{ {
@ -502,14 +501,15 @@ ISC_STATUS GDS_CLOSE_BLOB(ISC_STATUS * user_status, RBL * blob_handle)
* Close a completed blob. * Close a completed blob.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RBL blob = *blob_handle; RBL blob = *blob_handle;
CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle); CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle);
RDB rdb = blob->rbl_rdb; RDB rdb = blob->rbl_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status;
try try
{ {
@ -549,12 +549,13 @@ ISC_STATUS GDS_COMMIT(ISC_STATUS * user_status, RTR * rtr_handle)
* Commit a transaction. * Commit a transaction.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
RDB rdb = (*rtr_handle)->rtr_rdb; RDB rdb = (*rtr_handle)->rtr_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -588,12 +589,13 @@ ISC_STATUS GDS_COMMIT_RETAINING(ISC_STATUS * user_status, RTR * rtr_handle)
* Functional description * Functional description
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
RDB rdb = (*rtr_handle)->rtr_rdb; RDB rdb = (*rtr_handle)->rtr_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -631,13 +633,15 @@ ISC_STATUS GDS_COMPILE(ISC_STATUS* user_status,
* Functional description * Functional description
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
NULL_CHECK(req_handle, isc_bad_req_handle); NULL_CHECK(req_handle, isc_bad_req_handle);
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -740,11 +744,13 @@ ISC_STATUS GDS_CREATE_BLOB2(ISC_STATUS* user_status,
* Open an existing blob. * Open an existing blob.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
NULL_CHECK(blob_handle, isc_bad_segstr_handle); NULL_CHECK(blob_handle, isc_bad_segstr_handle);
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
@ -817,8 +823,6 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
* Create a nice, squeeky clean database, uncorrupted by user data. * Create a nice, squeeky clean database, uncorrupted by user data.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS* v = user_status; ISC_STATUS* v = user_status;
*v++ = isc_arg_gds; *v++ = isc_arg_gds;
*v++ = isc_unavailable; *v++ = isc_unavailable;
@ -852,6 +856,7 @@ ISC_STATUS GDS_CREATE_DATABASE(ISC_STATUS* user_status,
return user_status[1]; return user_status[1];
} }
Firebird::RefMutexGuard portGuard(*port->port_sync); // hvlad ???
rdb = port->port_context; rdb = port->port_context;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -896,13 +901,13 @@ ISC_STATUS GDS_DATABASE_INFO(ISC_STATUS* user_status,
* Provide information on database object. * Provide information on database object.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
UCHAR temp[1024]; UCHAR temp[1024];
RDB rdb = *handle; RDB rdb = *handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -921,8 +926,6 @@ ISC_STATUS GDS_DATABASE_INFO(ISC_STATUS* user_status,
if (!status) if (!status)
{ {
rem_port* port = rdb->rdb_port;
Firebird::string version; Firebird::string version;
version.printf("%s/%s", GDS_VERSION, port->port_version->str_data); version.printf("%s/%s", GDS_VERSION, port->port_version->str_data);
@ -960,14 +963,15 @@ ISC_STATUS GDS_DDL(ISC_STATUS* user_status,
* Functional description * Functional description
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
@ -1012,12 +1016,11 @@ ISC_STATUS GDS_DETACH(ISC_STATUS* user_status, RDB* handle)
* Close down a database. * Close down a database.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RDB rdb = *handle; RDB rdb = *handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -1090,15 +1093,14 @@ ISC_STATUS GDS_DROP_DATABASE(ISC_STATUS* user_status, RDB* handle)
* Close down and purge a database. * Close down and purge a database.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS_ARRAY local_status; ISC_STATUS_ARRAY local_status;
RDB rdb = *handle; RDB rdb = *handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port;
try try
{ {
@ -1156,11 +1158,12 @@ ISC_STATUS GDS_DSQL_ALLOCATE(ISC_STATUS* user_status,
* Allocate a statement handle. * Allocate a statement handle.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
NULL_CHECK(stmt_handle, isc_bad_req_handle); NULL_CHECK(stmt_handle, isc_bad_req_handle);
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -1260,19 +1263,20 @@ ISC_STATUS GDS_DSQL_EXECUTE2(ISC_STATUS* user_status,
* Execute a non-SELECT dynamic SQL statement. * Execute a non-SELECT dynamic SQL statement.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RSR statement = *stmt_handle; RSR statement = *stmt_handle;
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
if (transaction) { if (transaction) {
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
} }
rem_port* port = rdb->rdb_port;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -1486,18 +1490,19 @@ ISC_STATUS GDS_DSQL_EXECUTE_IMMED2(ISC_STATUS* user_status,
* Prepare and execute a statement. * Prepare and execute a statement.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
if (transaction) { if (transaction) {
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
} }
rem_port* port = rdb->rdb_port;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
if (dialect > 10) if (dialect > 10)
@ -1671,8 +1676,6 @@ ISC_STATUS GDS_DSQL_FETCH(ISC_STATUS* user_status,
* Fetch next record from a dynamic SQL cursor. * Fetch next record from a dynamic SQL cursor.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
@ -1681,6 +1684,8 @@ ISC_STATUS GDS_DSQL_FETCH(ISC_STATUS* user_status,
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -1952,13 +1957,14 @@ ISC_STATUS GDS_DSQL_FREE(ISC_STATUS * user_status, RSR * stmt_handle, USHORT opt
* Release request for a Dynamic SQL statement * Release request for a Dynamic SQL statement
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RSR statement = *stmt_handle; RSR statement = *stmt_handle;
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -2049,13 +2055,15 @@ ISC_STATUS GDS_DSQL_INSERT(ISC_STATUS * user_status,
* Insert next record into a dynamic SQL cursor. * Insert next record into a dynamic SQL cursor.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RSR statement = *stmt_handle; RSR statement = *stmt_handle;
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -2166,14 +2174,17 @@ ISC_STATUS GDS_DSQL_PREPARE(ISC_STATUS * user_status, RTR * rtr_handle, RSR * st
* Prepare a dynamic SQL statement for execution. * Prepare a dynamic SQL statement for execution.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RSR statement = *stmt_handle; RSR statement = *stmt_handle;
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
if (transaction) { if (transaction) {
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
@ -2306,13 +2317,15 @@ ISC_STATUS GDS_DSQL_SET_CURSOR(ISC_STATUS* user_status,
* parameter. * parameter.
* *
*****************************************/ *****************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RSR statement = *stmt_handle; RSR statement = *stmt_handle;
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -2397,8 +2410,6 @@ ISC_STATUS GDS_DSQL_SQL_INFO(ISC_STATUS* user_status,
* Provide information on sql object. * Provide information on sql object.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
@ -2406,6 +2417,9 @@ ISC_STATUS GDS_DSQL_SQL_INFO(ISC_STATUS* user_status,
RSR statement = *stmt_handle; RSR statement = *stmt_handle;
CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle); CHECK_HANDLE(statement, type_rsr, isc_bad_req_handle);
RDB rdb = statement->rsr_rdb; RDB rdb = statement->rsr_rdb;
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -2447,16 +2461,17 @@ ISC_STATUS GDS_GET_SEGMENT(ISC_STATUS * user_status,
* them one by one to the caller. * them one by one to the caller.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Sniff out handles, etc, and find the various blocks. */ /* Sniff out handles, etc, and find the various blocks. */
CHECK_HANDLE((*blob_handle), type_rbl, isc_bad_segstr_handle); CHECK_HANDLE((*blob_handle), type_rbl, isc_bad_segstr_handle);
RBL blob = *blob_handle; RBL blob = *blob_handle;
RDB rdb = blob->rbl_rdb; RDB rdb = blob->rbl_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
try try
{ {
@ -2674,10 +2689,11 @@ ISC_STATUS GDS_GET_SLICE(ISC_STATUS* user_status,
* Snatch a slice of an array. * Snatch a slice of an array.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
CHECK_HANDLE((*tra_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*tra_handle), type_rtr, isc_bad_trans_handle);
RTR transaction = *tra_handle; RTR transaction = *tra_handle;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -2774,11 +2790,13 @@ ISC_STATUS GDS_OPEN_BLOB2(ISC_STATUS* user_status,
* Open an existing blob. * Open an existing blob.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
NULL_CHECK(blob_handle, isc_bad_segstr_handle); NULL_CHECK(blob_handle, isc_bad_segstr_handle);
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -2846,11 +2864,13 @@ ISC_STATUS GDS_PREPARE(ISC_STATUS* user_status,
* phase commit. * phase commit.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
RDB rdb = (*rtr_handle)->rtr_rdb; RDB rdb = (*rtr_handle)->rtr_rdb;
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -2905,16 +2925,18 @@ ISC_STATUS GDS_PUT_SEGMENT(ISC_STATUS* user_status,
* batch put. * batch put.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Sniff out handles, etc, and find the various blocks. */ /* Sniff out handles, etc, and find the various blocks. */
CHECK_HANDLE((*blob_handle), type_rbl, isc_bad_segstr_handle); CHECK_HANDLE((*blob_handle), type_rbl, isc_bad_segstr_handle);
RBL blob = *blob_handle; RBL blob = *blob_handle;
RDB rdb = blob->rbl_rdb; RDB rdb = blob->rbl_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status;
try try
{ {
@ -2987,10 +3009,11 @@ ISC_STATUS GDS_PUT_SLICE(ISC_STATUS* user_status,
* Store a slice of an array. * Store a slice of an array.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
CHECK_HANDLE((*tra_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*tra_handle), type_rtr, isc_bad_trans_handle);
RTR transaction = *tra_handle; RTR transaction = *tra_handle;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -3077,12 +3100,12 @@ ISC_STATUS GDS_QUE_EVENTS(ISC_STATUS* user_status,
* Queue a request for event notification. * Queue a request for event notification.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RDB rdb = *handle; RDB rdb = *handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
PACKET* packet = &rdb->rdb_packet; PACKET* packet = &rdb->rdb_packet;
try try
@ -3182,19 +3205,21 @@ ISC_STATUS GDS_RECEIVE(ISC_STATUS * user_status,
* Remote server to send it to us if necessary. * Remote server to send it to us if necessary.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check handles and environment, then set up error handling */ /* Check handles and environment, then set up error handling */
CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle); CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle);
rrq* request = REMOTE_find_request(*req_handle, level); rrq* request = REMOTE_find_request(*req_handle, level);
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
{ {
rem_port* port = rdb->rdb_port;
rrq::rrq_repeat* tail = &request->rrq_rpt[msg_type]; rrq::rrq_repeat* tail = &request->rrq_rpt[msg_type];
REM_MSG message = tail->rrq_message; REM_MSG message = tail->rrq_message;
@ -3422,11 +3447,13 @@ ISC_STATUS GDS_RECONNECT(ISC_STATUS* user_status,
* Functional description * Functional description
* *
**************************************/ **************************************/
SchedulerContext scHolder;
NULL_CHECK(rtr_handle, isc_bad_trans_handle); NULL_CHECK(rtr_handle, isc_bad_trans_handle);
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3465,12 +3492,14 @@ ISC_STATUS GDS_RELEASE_REQUEST(ISC_STATUS * user_status, rrq** req_handle)
* Release a request. * Release a request.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
rrq* request = *req_handle; rrq* request = *req_handle;
CHECK_HANDLE(request, type_rrq, isc_bad_req_handle); CHECK_HANDLE(request, type_rrq, isc_bad_req_handle);
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3507,14 +3536,16 @@ ISC_STATUS GDS_REQUEST_INFO(ISC_STATUS* user_status,
* Provide information on request object. * Provide information on request object.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
rrq* request = REMOTE_find_request(*req_handle, level); rrq* request = REMOTE_find_request(*req_handle, level);
CHECK_HANDLE(request, type_rrq, isc_bad_req_handle); CHECK_HANDLE(request, type_rrq, isc_bad_req_handle);
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3601,12 +3632,14 @@ ISC_STATUS GDS_ROLLBACK_RETAINING(ISC_STATUS * user_status, RTR * rtr_handle)
* Abort a transaction but keep its environment valid * Abort a transaction but keep its environment valid
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
RDB rdb = (*rtr_handle)->rtr_rdb; RDB rdb = (*rtr_handle)->rtr_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3642,12 +3675,14 @@ ISC_STATUS GDS_ROLLBACK(ISC_STATUS * user_status, RTR * rtr_handle)
* Abort a transaction. * Abort a transaction.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
RDB rdb = (*rtr_handle)->rtr_rdb; RDB rdb = (*rtr_handle)->rtr_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3683,12 +3718,14 @@ ISC_STATUS GDS_SEEK_BLOB(ISC_STATUS * user_status,
* Seek into a blob. * Seek into a blob.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RBL blob = *blob_handle; RBL blob = *blob_handle;
CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle); CHECK_HANDLE(blob, type_rbl, isc_bad_segstr_handle);
RDB rdb = blob->rbl_rdb; RDB rdb = blob->rbl_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3741,12 +3778,14 @@ ISC_STATUS GDS_SEND(ISC_STATUS * user_status,
* Send a message to the server. * Send a message to the server.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle); CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle);
rrq* request = REMOTE_find_request(*req_handle, level); rrq* request = REMOTE_find_request(*req_handle, level);
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
if (msg_type > request->rrq_max_msg) if (msg_type > request->rrq_max_msg)
return handle_error(user_status, isc_badmsgnum); return handle_error(user_status, isc_badmsgnum);
@ -3802,8 +3841,6 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
* Connect to a Firebird service. * Connect to a Firebird service.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
NULL_CHECK(handle, isc_bad_svc_handle); NULL_CHECK(handle, isc_bad_svc_handle);
Firebird::PathName expanded_name; Firebird::PathName expanded_name;
@ -3835,6 +3872,7 @@ ISC_STATUS GDS_SERVICE_ATTACH(ISC_STATUS* user_status,
return user_status[1]; return user_status[1];
} }
Firebird::RefMutexGuard portGuard(*port->port_sync); // hvlad ???
rdb = port->port_context; rdb = port->port_context;
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -3879,14 +3917,15 @@ ISC_STATUS GDS_SERVICE_DETACH(ISC_STATUS * user_status, RDB * handle)
* Close down a connection to a Firebird service. * Close down a connection to a Firebird service.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RDB rdb = *handle; RDB rdb = *handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_svc_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_svc_handle);
rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port; rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status;
try try
{ {
@ -3942,14 +3981,15 @@ ISC_STATUS GDS_SERVICE_QUERY(ISC_STATUS* user_status,
* network). This parameter will be implemented at * network). This parameter will be implemented at
* a later date. * a later date.
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RDB rdb = *svc_handle; RDB rdb = *svc_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_svc_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_svc_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -3992,14 +4032,15 @@ ISC_STATUS GDS_SERVICE_START(ISC_STATUS * user_status,
* network). This parameter will be implemented at * network). This parameter will be implemented at
* a later date. * a later date.
**************************************/ **************************************/
SchedulerContext scHolder;
ISC_STATUS status; ISC_STATUS status;
/* Check and validate handles, etc. */ /* Check and validate handles, etc. */
RDB rdb = *svc_handle; RDB rdb = *svc_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_svc_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_svc_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -4039,14 +4080,16 @@ ISC_STATUS GDS_START_AND_SEND(ISC_STATUS * user_status,
* Get a record from the host program. * Get a record from the host program.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle); CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle);
CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle);
rrq* request = REMOTE_find_request(*req_handle, level); rrq* request = REMOTE_find_request(*req_handle, level);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
if (msg_type > request->rrq_max_msg) if (msg_type > request->rrq_max_msg)
return handle_error(user_status, isc_badmsgnum); return handle_error(user_status, isc_badmsgnum);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
@ -4122,14 +4165,16 @@ ISC_STATUS GDS_START(ISC_STATUS * user_status,
* Get a record from the host program. * Get a record from the host program.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle); CHECK_HANDLE((*req_handle), type_rrq, isc_bad_req_handle);
CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle); CHECK_HANDLE((*rtr_handle), type_rtr, isc_bad_trans_handle);
rrq* request = REMOTE_find_request(*req_handle, level); rrq* request = REMOTE_find_request(*req_handle, level);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -4192,11 +4237,13 @@ ISC_STATUS GDS_START_TRANSACTION(ISC_STATUS* user_status,
* Start a transaction. * Start a transaction.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
NULL_CHECK(rtr_handle, isc_bad_trans_handle); NULL_CHECK(rtr_handle, isc_bad_trans_handle);
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -4248,14 +4295,14 @@ ISC_STATUS GDS_TRANSACT_REQUEST(ISC_STATUS* user_status,
* Execute a procedure on remote host. * Execute a procedure on remote host.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RDB rdb = *db_handle; RDB rdb = *db_handle;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
RTR transaction = *rtr_handle; RTR transaction = *rtr_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
rem_port* port = rdb->rdb_port;
try try
{ {
@ -4382,12 +4429,14 @@ ISC_STATUS GDS_TRANSACTION_INFO(ISC_STATUS* user_status,
* Functional description * Functional description
* *
**************************************/ **************************************/
SchedulerContext scHolder;
RTR transaction = *tra_handle; RTR transaction = *tra_handle;
CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle); CHECK_HANDLE(transaction, type_rtr, isc_bad_trans_handle);
RDB rdb = transaction->rtr_rdb; RDB rdb = transaction->rtr_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
ISC_STATUS status; ISC_STATUS status;
@ -4419,12 +4468,14 @@ ISC_STATUS GDS_UNWIND(ISC_STATUS* user_status, rrq** req_handle, USHORT level)
* Unwind a running request. * Unwind a running request.
* *
**************************************/ **************************************/
SchedulerContext scHolder;
rrq* request = REMOTE_find_request(*req_handle, level); rrq* request = REMOTE_find_request(*req_handle, level);
CHECK_HANDLE(request, type_rrq, isc_bad_req_handle); CHECK_HANDLE(request, type_rrq, isc_bad_req_handle);
RDB rdb = request->rrq_rdb; RDB rdb = request->rrq_rdb;
CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle); CHECK_HANDLE(rdb, type_rdb, isc_bad_db_handle);
rem_port* port = rdb->rdb_port;
Firebird::RefMutexGuard portGuard(*port->port_sync);
rdb->rdb_status_vector = user_status; rdb->rdb_status_vector = user_status;
try try
@ -5333,6 +5384,7 @@ static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM arg)
rem_port* port = (rem_port*)arg; rem_port* port = (rem_port*)arg;
PACKET packet; PACKET packet;
Firebird::RefMutexGuard portGuard(*port->port_sync);
for (;;) { for (;;) {
/* zero packet */ /* zero packet */
@ -5340,9 +5392,7 @@ static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM arg)
/* read what should be an event message */ /* read what should be an event message */
THREAD_ENTER();
rem_port* stuff = port->receive(&packet); rem_port* stuff = port->receive(&packet);
THREAD_EXIT();
const P_OP operation = packet.p_operation; const P_OP operation = packet.p_operation;
@ -5360,9 +5410,7 @@ static THREAD_ENTRY_DECLARE event_thread(THREAD_ENTRY_PARAM arg)
if (operation == op_event) { if (operation == op_event) {
P_EVENT* pevent = &packet.p_event; P_EVENT* pevent = &packet.p_event;
THREAD_ENTER();
RVNT event = find_event(port, pevent->p_event_rid); RVNT event = find_event(port, pevent->p_event_rid);
THREAD_EXIT();
if (event) { if (event) {
/* Call the asynchronous event routine associated /* Call the asynchronous event routine associated
@ -6772,9 +6820,7 @@ static void send_cancel_event(RVNT event)
if (event->rvnt_id) if (event->rvnt_id)
{ {
THREAD_EXIT();
(*event->rvnt_ast)(event->rvnt_arg, (USHORT) 0, NULL); (*event->rvnt_ast)(event->rvnt_arg, (USHORT) 0, NULL);
THREAD_ENTER();
event->rvnt_id = 0; event->rvnt_id = 0;
} }
} }
@ -6881,7 +6927,6 @@ static void server_death(rem_port* port)
* Cleanup events. * Cleanup events.
* *
**************************************/ **************************************/
THREAD_ENTER();
RDB rdb = port->port_context; RDB rdb = port->port_context;
if (!(port->port_flags & PORT_disconnect)) if (!(port->port_flags & PORT_disconnect))
@ -6890,16 +6935,13 @@ static void server_death(rem_port* port)
{ {
if (event->rvnt_id) if (event->rvnt_id)
{ {
THREAD_EXIT();
(*event->rvnt_ast) (event->rvnt_arg, (USHORT) 0, NULL); (*event->rvnt_ast) (event->rvnt_arg, (USHORT) 0, NULL);
THREAD_ENTER();
event->rvnt_id = 0; event->rvnt_id = 0;
} }
} }
} }
port->disconnect(); port->disconnect();
THREAD_EXIT();
} }

View File

@ -34,7 +34,6 @@
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h" #include "../jrd/thread_proto.h"
#include "../jrd/jrd_proto.h" #include "../jrd/jrd_proto.h"
#include "../jrd/why_proto.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#ifdef WIN_NT #ifdef WIN_NT
@ -145,7 +144,6 @@ void WINAPI CNTL_main_thread( DWORD argc, char* argv[])
report_status(SERVICE_STOP_PENDING, NO_ERROR, 1, SHUTDOWN_TIMEOUT); report_status(SERVICE_STOP_PENDING, NO_ERROR, 1, SHUTDOWN_TIMEOUT);
fb_shutdown(NULL, SHUTDOWN_TIMEOUT); fb_shutdown(NULL, SHUTDOWN_TIMEOUT);
SRVR_shutdown();
report_status(SERVICE_STOPPED, last_error, 0, 0); report_status(SERVICE_STOPPED, last_error, 0, 0);
} }

View File

@ -98,7 +98,6 @@
#include "../remote/xnet_proto.h" #include "../remote/xnet_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../jrd/isc_proto.h" #include "../jrd/isc_proto.h"
#include "../jrd/jrd_proto.h" #include "../jrd/jrd_proto.h"
#include "../jrd/os/isc_i_proto.h" #include "../jrd/os/isc_i_proto.h"
@ -141,6 +140,10 @@ int WINAPI WinMain(HINSTANCE hThisInst,
**************************************/ **************************************/
hInst = hThisInst; hInst = hThisInst;
#ifndef SUPERSERVER
//MessageBox(NULL, "Debug me", "Please", MB_OK);
#endif
// We want server to crash without waiting for feedback from the user // We want server to crash without waiting for feedback from the user
try try
{ {
@ -185,12 +188,6 @@ int WINAPI WinMain(HINSTANCE hThisInst,
HANDLE connection_handle = parse_args(lpszArgs, &server_flag); HANDLE connection_handle = parse_args(lpszArgs, &server_flag);
if ((server_flag & (SRVR_inet | SRVR_wnet | SRVR_xnet)) == 0) {
server_flag |= SRVR_wnet;
server_flag |= SRVR_inet;
server_flag |= SRVR_xnet;
}
#ifdef SUPERSERVER #ifdef SUPERSERVER
// get priority class from the config file // get priority class from the config file
int priority = Config::getProcessPriorityLevel(); int priority = Config::getProcessPriorityLevel();
@ -213,10 +210,7 @@ int WINAPI WinMain(HINSTANCE hThisInst,
Setup sig_mutex for the process Setup sig_mutex for the process
*/ */
ISC_signal_init(); ISC_signal_init();
#ifdef SUPERSERVER
ISC_enter(); ISC_enter();
#endif
int nReturnValue = 0; int nReturnValue = 0;
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
@ -224,14 +218,14 @@ int WINAPI WinMain(HINSTANCE hThisInst,
if (connection_handle != INVALID_HANDLE_VALUE) if (connection_handle != INVALID_HANDLE_VALUE)
{ {
rem_port* port = 0; rem_port* port = 0;
THREAD_ENTER();
if (server_flag & SRVR_inet) if (server_flag & SRVR_inet)
port = INET_reconnect(connection_handle, status_vector); port = INET_reconnect(connection_handle, status_vector);
else if (server_flag & SRVR_wnet) else if (server_flag & SRVR_wnet)
port = WNET_reconnect(connection_handle, status_vector); port = WNET_reconnect(connection_handle, status_vector);
else if (server_flag & SRVR_xnet) else if (server_flag & SRVR_xnet)
port = XNET_reconnect((ULONG) connection_handle, status_vector); port = XNET_reconnect((ULONG) connection_handle, status_vector);
THREAD_EXIT();
if (port) { if (port) {
service_connection(port); service_connection(port);
} }
@ -264,19 +258,7 @@ int WINAPI WinMain(HINSTANCE hThisInst,
} }
else else
{ {
if (server_flag & SRVR_inet) { start_connections_thread(0);
gds__thread_start(inet_connect_wait_thread, 0, THREAD_medium, 0,
0);
}
if (server_flag & SRVR_wnet) {
gds__thread_start(wnet_connect_wait_thread, 0, THREAD_medium, 0,
0);
}
if (server_flag & SRVR_xnet) {
gds__thread_start(xnet_connect_wait_thread, 0, THREAD_medium, 0,
0);
}
nReturnValue = WINDOW_main(hThisInst, nWndMode, server_flag); nReturnValue = WINDOW_main(hThisInst, nWndMode, server_flag);
} }
@ -341,10 +323,8 @@ static THREAD_ENTRY_DECLARE inet_connect_wait_thread(THREAD_ENTRY_PARAM)
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
while (true) while (true)
{ {
THREAD_ENTER(); rem_port* port = INET_connect(protocol_inet, NULL, status_vector, server_flag, 0);
rem_port* port =
INET_connect(protocol_inet, NULL, status_vector, server_flag, 0);
THREAD_EXIT();
if (!port) { if (!port) {
gds__log_status(0, status_vector); gds__log_status(0, status_vector);
break; break;
@ -354,8 +334,7 @@ static THREAD_ENTRY_DECLARE inet_connect_wait_thread(THREAD_ENTRY_PARAM)
break; break;
} }
else { else {
gds__thread_start(process_connection_thread, port, gds__thread_start(process_connection_thread, port, THREAD_medium, 0, 0);
THREAD_medium, 0, 0);
} }
} }
@ -385,10 +364,8 @@ static THREAD_ENTRY_DECLARE wnet_connect_wait_thread(THREAD_ENTRY_PARAM)
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
while (true) while (true)
{ {
THREAD_ENTER(); rem_port* port = WNET_connect(protocol_wnet, NULL, status_vector, server_flag);
rem_port* port =
WNET_connect(protocol_wnet, NULL, status_vector, server_flag);
THREAD_EXIT();
if (!port) { if (!port) {
if (status_vector[1] != isc_io_error || if (status_vector[1] != isc_io_error ||
status_vector[6] != isc_arg_win32 || status_vector[6] != isc_arg_win32 ||
@ -398,8 +375,7 @@ static THREAD_ENTRY_DECLARE wnet_connect_wait_thread(THREAD_ENTRY_PARAM)
} }
break; break;
} }
gds__thread_start(process_connection_thread, port, gds__thread_start(process_connection_thread, port, THREAD_medium, 0, 0);
THREAD_medium, 0, 0);
} }
if (!(server_flag & SRVR_non_service)) { if (!(server_flag & SRVR_non_service)) {
@ -429,16 +405,13 @@ static THREAD_ENTRY_DECLARE xnet_connect_wait_thread(THREAD_ENTRY_PARAM)
ISC_STATUS_ARRAY status_vector; ISC_STATUS_ARRAY status_vector;
while (true) while (true)
{ {
THREAD_ENTER(); rem_port* port = XNET_connect(NULL, NULL, status_vector, server_flag);
rem_port* port =
XNET_connect(NULL, NULL, status_vector, server_flag);
THREAD_EXIT();
if (!port) { if (!port) {
gds__log_status(0, status_vector); gds__log_status(0, status_vector);
break; break;
} }
gds__thread_start(process_connection_thread, port, gds__thread_start(process_connection_thread, port, THREAD_medium, 0, 0);
THREAD_medium, 0, 0);
} }
if (!(server_flag & SRVR_non_service)) if (!(server_flag & SRVR_non_service))
@ -475,6 +448,8 @@ static THREAD_ENTRY_DECLARE start_connections_thread(THREAD_ENTRY_PARAM)
* *
**************************************/ **************************************/
fb_shutdown_callback(0, SRVR_shutdown, fb_shut_postproviders);
if (server_flag & SRVR_inet) { if (server_flag & SRVR_inet) {
gds__thread_start(inet_connect_wait_thread, 0, THREAD_medium, 0, 0); gds__thread_start(inet_connect_wait_thread, 0, THREAD_medium, 0, 0);
} }
@ -640,5 +615,16 @@ static HANDLE parse_args(LPCSTR lpszArgs, USHORT* pserver_flag)
} }
} }
} }
if ((*pserver_flag & (SRVR_inet | SRVR_wnet | SRVR_xnet)) == 0) {
*pserver_flag |= SRVR_wnet;
*pserver_flag |= SRVR_inet;
*pserver_flag |= SRVR_xnet;
}
if (*pserver_flag & SRVR_debug) {
*pserver_flag |= SRVR_multi_client;
}
return connection_handle; return connection_handle;
} }

View File

@ -39,7 +39,6 @@
#include "../remote/os/win32/window_proto.h" #include "../remote/os/win32/window_proto.h"
#include "../remote/os/win32/propty_proto.h" #include "../remote/os/win32/propty_proto.h"
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/why_proto.h"
#include "../remote/os/win32/window.h" #include "../remote/os/win32/window.h"
#include "../jrd/isc_proto.h" #include "../jrd/isc_proto.h"
@ -52,9 +51,10 @@
#include "../common/config/config.h" #include "../common/config/config.h"
HWND hPSDlg = NULL; static HWND hPSDlg = NULL;
static HINSTANCE hInstance = NULL; static HINSTANCE hInstance = NULL;
static USHORT usServerFlags; static USHORT usServerFlags;
static HWND hMainWnd = NULL;
// Static functions to be called from this file only. // Static functions to be called from this file only.
static void GetDriveLetter(ULONG, char pchBuf[DRV_STRINGLEN]); static void GetDriveLetter(ULONG, char pchBuf[DRV_STRINGLEN]);
@ -66,6 +66,7 @@ static BOOL CanEndServer(HWND, bool);
// Window Procedure // Window Procedure
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
static int fb_shutdown_cb();
int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask) int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask)
{ {
@ -90,6 +91,8 @@ int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask)
hInstance = hThisInst; hInstance = hThisInst;
usServerFlags = usServerFlagMask; usServerFlags = usServerFlagMask;
fb_shutdown_callback(0, fb_shutdown_cb, fb_shut_postproviders);
/* initialize main window */ /* initialize main window */
WNDCLASS wcl; WNDCLASS wcl;
@ -115,7 +118,7 @@ int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask)
return 0; return 0;
} }
hWnd = CreateWindowEx(0, hMainWnd = hWnd = CreateWindowEx(0,
szClassName, szClassName,
APP_NAME, APP_NAME,
WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX, WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX,
@ -214,8 +217,7 @@ LRESULT CALLBACK WindowFunc(HWND hWnd,
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
} }
fb_shutdown(NULL, 0); fb_shutdown(NULL, 0);
SRVR_shutdown(); //DestroyWindow(hWnd);
DestroyWindow(hWnd);
} }
} }
break; break;
@ -427,8 +429,7 @@ LRESULT CALLBACK WindowFunc(HWND hWnd,
} }
fb_shutdown(NULL, 0); fb_shutdown(NULL, 0);
SRVR_shutdown(); //DestroyWindow(hWnd);
PostMessage(hWnd, WM_DESTROY, 0, 0);
return TRUE; return TRUE;
} }
/* Fall through to MOVEPENDING if we receive a QUERYDEVICE for the /* Fall through to MOVEPENDING if we receive a QUERYDEVICE for the
@ -449,9 +450,8 @@ LRESULT CALLBACK WindowFunc(HWND hWnd,
IDS_PNP2, p, TMP_STRINGLEN - (p - tmp)); IDS_PNP2, p, TMP_STRINGLEN - (p - tmp));
GetDriveLetter(pdbcv->dbcv_unitmask, szDrives); GetDriveLetter(pdbcv->dbcv_unitmask, szDrives);
MessageBox(hWnd, tmp, szDrives, MB_OK | MB_ICONHAND); MessageBox(hWnd, tmp, szDrives, MB_OK | MB_ICONHAND);
fb_shutdown(NULL, 0);
SRVR_shutdown();
PostMessage(hWnd, WM_DESTROY, 0, 0); PostMessage(hWnd, WM_DESTROY, 0, 0);
fb_shutdown(NULL, 0);
} }
return TRUE; return TRUE;
@ -539,3 +539,11 @@ BOOL CanEndServer(HWND hWnd, bool bSysExit)
MB_ICONQUESTION | MB_OKCANCEL) == IDOK); MB_ICONQUESTION | MB_OKCANCEL) == IDOK);
} }
static int fb_shutdown_cb()
{
if (hMainWnd)
DestroyWindow(hMainWnd);
return 0;
}

View File

@ -43,7 +43,6 @@
#include "../jrd/isc_proto.h" #include "../jrd/isc_proto.h"
#include "../jrd/isc_f_proto.h" #include "../jrd/isc_f_proto.h"
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/config/config.h" #include "../common/config/config.h"
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
@ -55,6 +54,7 @@ const int BUFFER_SIZE = MAX_DATA;
const char* PIPE_PREFIX = "pipe"; // win32-specific const char* PIPE_PREFIX = "pipe"; // win32-specific
const char* SERVER_PIPE_SUFFIX = "server"; const char* SERVER_PIPE_SUFFIX = "server";
const char* EVENT_PIPE_SUFFIX = "event"; const char* EVENT_PIPE_SUFFIX = "event";
Firebird::AtomicCounter event_counter;
static int accept_connection(rem_port*, P_CNCT *); static int accept_connection(rem_port*, P_CNCT *);
@ -335,7 +335,6 @@ rem_port* WNET_connect(const TEXT* name,
if (packet) if (packet)
{ {
THREAD_EXIT();
while (true) { while (true) {
port->port_handle = CreateFile(port->port_connection->str_data, port->port_handle = CreateFile(port->port_connection->str_data,
GENERIC_WRITE | GENERIC_READ, GENERIC_WRITE | GENERIC_READ,
@ -345,14 +344,12 @@ rem_port* WNET_connect(const TEXT* name,
} }
const ISC_STATUS status = GetLastError(); const ISC_STATUS status = GetLastError();
if (status != ERROR_PIPE_BUSY) { if (status != ERROR_PIPE_BUSY) {
THREAD_ENTER();
wnet_error(port, "CreateFile", isc_net_connect_err, status); wnet_error(port, "CreateFile", isc_net_connect_err, status);
disconnect(port); disconnect(port);
return NULL; return NULL;
} }
WaitNamedPipe(port->port_connection->str_data, 3000L); WaitNamedPipe(port->port_connection->str_data, 3000L);
} }
THREAD_ENTER();
send_full(port, packet); send_full(port, packet);
return port; return port;
} }
@ -360,7 +357,6 @@ rem_port* WNET_connect(const TEXT* name,
/* We're a server, so wait for a host to show up */ /* We're a server, so wait for a host to show up */
LPSECURITY_ATTRIBUTES security_attr = ISC_get_security_desc(); LPSECURITY_ATTRIBUTES security_attr = ISC_get_security_desc();
THREAD_EXIT();
while (true) while (true)
{ {
@ -379,7 +375,6 @@ rem_port* WNET_connect(const TEXT* name,
// TMN: The check for GetLastError() is redundant. // TMN: The check for GetLastError() is redundant.
// This code should NEVER be called if not running on NT, // This code should NEVER be called if not running on NT,
// since Win9x does not support the server side of named pipes! // since Win9x does not support the server side of named pipes!
THREAD_ENTER();
wnet_error(port, "CreateNamedPipe", isc_net_connect_listen_err, wnet_error(port, "CreateNamedPipe", isc_net_connect_listen_err,
ERRNO); ERRNO);
disconnect(port); disconnect(port);
@ -389,7 +384,6 @@ rem_port* WNET_connect(const TEXT* name,
if (!ConnectNamedPipe(port->port_handle, 0) && if (!ConnectNamedPipe(port->port_handle, 0) &&
GetLastError() != ERROR_PIPE_CONNECTED) GetLastError() != ERROR_PIPE_CONNECTED)
{ {
THREAD_ENTER();
wnet_error(port, "ConnectNamedPipe", isc_net_connect_err, ERRNO); wnet_error(port, "ConnectNamedPipe", isc_net_connect_err, ERRNO);
disconnect(port); disconnect(port);
return NULL; return NULL;
@ -397,7 +391,6 @@ rem_port* WNET_connect(const TEXT* name,
if (flag & (SRVR_debug | SRVR_multi_client)) if (flag & (SRVR_debug | SRVR_multi_client))
{ {
THREAD_ENTER();
port->port_server_flags |= SRVR_server; port->port_server_flags |= SRVR_server;
if (flag & SRVR_multi_client) if (flag & SRVR_multi_client)
{ {
@ -588,6 +581,13 @@ static rem_port* alloc_port( rem_port* parent)
port->port_request = aux_request; port->port_request = aux_request;
port->port_buff_size = BUFFER_SIZE; port->port_buff_size = BUFFER_SIZE;
port->port_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_sync->addRef();
#ifdef REM_SERVER
port->port_que_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_que_sync->addRef();
#endif
xdrwnet_create(&port->port_send, port, xdrwnet_create(&port->port_send, port,
&port->port_buffer[BUFFER_SIZE], BUFFER_SIZE, XDR_ENCODE); &port->port_buffer[BUFFER_SIZE], BUFFER_SIZE, XDR_ENCODE);
@ -651,7 +651,6 @@ static rem_port* aux_connect( rem_port* port, PACKET* packet, t_event_ast ast)
new_port->port_connection = new_port->port_connection =
make_pipe_name(port->port_connection->str_data, EVENT_PIPE_SUFFIX, p); make_pipe_name(port->port_connection->str_data, EVENT_PIPE_SUFFIX, p);
THREAD_EXIT();
while (true) { while (true) {
new_port->port_handle = new_port->port_handle =
CreateFile(new_port->port_connection->str_data, GENERIC_READ, 0, CreateFile(new_port->port_connection->str_data, GENERIC_READ, 0,
@ -660,15 +659,12 @@ static rem_port* aux_connect( rem_port* port, PACKET* packet, t_event_ast ast)
break; break;
const ISC_STATUS status = GetLastError(); const ISC_STATUS status = GetLastError();
if (status != ERROR_PIPE_BUSY) { if (status != ERROR_PIPE_BUSY) {
THREAD_ENTER();
return (rem_port*) wnet_error(new_port, "CreateFile", return (rem_port*) wnet_error(new_port, "CreateFile",
isc_net_event_connect_err, status); isc_net_event_connect_err, status);
} }
WaitNamedPipe(new_port->port_connection->str_data, 3000L); WaitNamedPipe(new_port->port_connection->str_data, 3000L);
} }
THREAD_ENTER();
return new_port; return new_port;
} }
@ -691,7 +687,8 @@ static rem_port* aux_request( rem_port* vport, PACKET* packet)
**************************************/ **************************************/
rem_port* new_port = NULL; // If this is the client, we will return NULL rem_port* new_port = NULL; // If this is the client, we will return NULL
const DWORD server_pid = GetCurrentProcessId(); const DWORD server_pid = (vport->port_server_flags & SRVR_multi_client) ?
++event_counter : GetCurrentProcessId();
vport->port_async = new_port = alloc_port(vport->port_parent); vport->port_async = new_port = alloc_port(vport->port_parent);
new_port->port_server_flags = vport->port_server_flags; new_port->port_server_flags = vport->port_server_flags;
new_port->port_flags = vport->port_flags & PORT_no_oob; new_port->port_flags = vport->port_flags & PORT_no_oob;
@ -702,7 +699,7 @@ static rem_port* aux_request( rem_port* vport, PACKET* packet)
make_pipe_name(vport->port_connection->str_data, EVENT_PIPE_SUFFIX, str_pid); make_pipe_name(vport->port_connection->str_data, EVENT_PIPE_SUFFIX, str_pid);
LPSECURITY_ATTRIBUTES security_attr = ISC_get_security_desc(); LPSECURITY_ATTRIBUTES security_attr = ISC_get_security_desc();
THREAD_EXIT();
new_port->port_handle = new_port->port_handle =
CreateNamedPipe(new_port->port_connection->str_data, CreateNamedPipe(new_port->port_connection->str_data,
PIPE_ACCESS_DUPLEX, PIPE_ACCESS_DUPLEX,
@ -712,7 +709,7 @@ static rem_port* aux_request( rem_port* vport, PACKET* packet)
MAX_DATA, MAX_DATA,
0, 0,
security_attr); security_attr);
THREAD_ENTER();
if (new_port->port_handle == INVALID_HANDLE_VALUE) { if (new_port->port_handle == INVALID_HANDLE_VALUE) {
wnet_error(new_port, "CreateNamedPipe", isc_net_event_listen_err, wnet_error(new_port, "CreateNamedPipe", isc_net_event_listen_err,
ERRNO); ERRNO);
@ -827,6 +824,11 @@ static void cleanup_port( rem_port* port)
ALLR_free(port->port_packet_vector); ALLR_free(port->port_packet_vector);
#endif #endif
port->port_sync->release();
#ifdef REM_SERVER
port->port_que_sync->release();
#endif
ALLR_free(port); ALLR_free(port);
return; return;
} }
@ -1453,15 +1455,12 @@ static int packet_receive(
**************************************/ **************************************/
DWORD n = 0; DWORD n = 0;
THREAD_EXIT(); const USHORT status = ReadFile(port->port_handle, buffer, buffer_length, &n, NULL);
const USHORT status =
ReadFile(port->port_handle, buffer, buffer_length, &n, NULL);
THREAD_ENTER();
if (!status && GetLastError() != ERROR_BROKEN_PIPE) if (!status && GetLastError() != ERROR_BROKEN_PIPE)
return wnet_error(port, "ReadFile", isc_net_read_err, ERRNO); return wnet_error(port, "ReadFile", isc_net_read_err, ERRNO);
if (!n) if (!n)
return wnet_error(port, "ReadFile end-of-file", isc_net_read_err, return wnet_error(port, "ReadFile end-of-file", isc_net_read_err, ERRNO);
ERRNO);
#if defined(DEBUG) && defined(WNET_trace) #if defined(DEBUG) && defined(WNET_trace)
packet_print("receive", buffer, n); packet_print("receive", buffer, n);
@ -1488,10 +1487,9 @@ static int packet_send( rem_port* port, const SCHAR* buffer, SSHORT buffer_lengt
const SCHAR* data = buffer; const SCHAR* data = buffer;
const DWORD length = buffer_length; const DWORD length = buffer_length;
THREAD_EXIT();
DWORD n; DWORD n;
const USHORT status = WriteFile(port->port_handle, data, length, &n, NULL); const USHORT status = WriteFile(port->port_handle, data, length, &n, NULL);
THREAD_ENTER();
if (!status) if (!status)
return wnet_error(port, "WriteFile", isc_net_write_err, ERRNO); return wnet_error(port, "WriteFile", isc_net_write_err, ERRNO);
if (n != length) if (n != length)

View File

@ -735,7 +735,7 @@ rem_port* rem_port::request(PACKET* pckt)
return (*this->port_request)(this, pckt); return (*this->port_request)(this, pckt);
} }
#ifdef SUPERSERVER #ifdef REM_SERVER
bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count) bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count)
{ {
/************************************** /**************************************
@ -768,6 +768,7 @@ bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count)
xdrs->x_handy = 0; xdrs->x_handy = 0;
} }
rem_port* port = (rem_port*) xdrs->x_public; rem_port* port = (rem_port*) xdrs->x_public;
Firebird::RefMutexGuard queGuard(*port->port_que_sync);
if (port->port_qoffset >= port->port_queue->getCount()) { if (port->port_qoffset >= port->port_queue->getCount()) {
port->port_flags |= PORT_partial_data; port->port_flags |= PORT_partial_data;
return FALSE; return FALSE;
@ -782,7 +783,7 @@ bool_t REMOTE_getbytes (XDR * xdrs, SCHAR * buff, u_int count)
return TRUE; return TRUE;
} }
#endif //SUPERSERVER #endif //REM_SERVER
#ifdef TRUSTED_AUTH #ifdef TRUSTED_AUTH
ServerAuth::ServerAuth(const char* fName, int fLen, const Firebird::ClumpletWriter& pb, ServerAuth::ServerAuth(const char* fName, int fLen, const Firebird::ClumpletWriter& pb,

View File

@ -40,6 +40,10 @@
#include "../common/classes/ClumpletWriter.h" #include "../common/classes/ClumpletWriter.h"
#include "../common/StatusHolder.h" #include "../common/StatusHolder.h"
#if !defined(SUPERCLIENT) && !defined(EMBEDDED)
#define REM_SERVER
#endif
/* Include some apollo include files for tasking */ /* Include some apollo include files for tasking */
#ifndef WIN_NT #ifndef WIN_NT
@ -481,13 +485,15 @@ struct rem_port
void* port_xcc; /* interprocess structure */ void* port_xcc; /* interprocess structure */
PacketQueue* port_deferred_packets; /* queue of deferred packets */ PacketQueue* port_deferred_packets; /* queue of deferred packets */
OBJCT port_last_object_id; /* cached last id */ OBJCT port_last_object_id; /* cached last id */
#ifdef SUPERSERVER #ifdef REM_SERVER
Firebird::ObjectsArray< Firebird::Array< char > >* port_queue; Firebird::ObjectsArray< Firebird::Array< char > >* port_queue;
size_t port_qoffset; // current packet in the queue size_t port_qoffset; // current packet in the queue
Firebird::RefMutex *port_que_sync;
#endif #endif
#ifdef TRUSTED_AUTH #ifdef TRUSTED_AUTH
ServerAuth* port_trusted_auth; ServerAuth* port_trusted_auth;
#endif #endif
Firebird::RefMutex *port_sync;
UCHAR port_buffer[1]; UCHAR port_buffer[1];
/* TMN: Beginning of C++ port */ /* TMN: Beginning of C++ port */
@ -501,22 +507,21 @@ struct rem_port
rem_port* request(PACKET* pckt); rem_port* request(PACKET* pckt);
rem_port* select_multi(UCHAR* buffer, SSHORT bufsize, SSHORT* length); rem_port* select_multi(UCHAR* buffer, SSHORT bufsize, SSHORT* length);
#ifdef REM_SERVER
bool haveRecvData() const bool haveRecvData() const
{ {
Firebird::RefMutexGuard queGuard(*port_que_sync);
return (port_receive.x_handy > 0 return (port_receive.x_handy > 0
#ifdef SUPERSERVER
|| port_queue && (port_qoffset < port_queue->getCount()) || port_queue && (port_qoffset < port_queue->getCount())
#endif
); );
} }
void clearRecvQue() void clearRecvQue()
{ {
#ifdef SUPERSERVER Firebird::RefMutexGuard queGuard(*port_que_sync);
if (port_queue) if (port_queue)
port_queue->clear(); port_queue->clear();
port_qoffset = 0; port_qoffset = 0;
#endif
port_receive.x_private = port_receive.x_base; port_receive.x_private = port_receive.x_base;
} }
@ -525,17 +530,13 @@ struct rem_port
public: public:
int save_handy; int save_handy;
size_t save_private; size_t save_private;
#ifdef SUPERSERVER
size_t save_qoffset; size_t save_qoffset;
#endif
RecvQueState(const rem_port* port) RecvQueState(const rem_port* port)
{ {
save_handy = port->port_receive.x_handy; save_handy = port->port_receive.x_handy;
save_private = port->port_receive.x_private - port->port_receive.x_base; save_private = port->port_receive.x_private - port->port_receive.x_base;
#ifdef SUPERSERVER
save_qoffset = port->port_qoffset; save_qoffset = port->port_qoffset;
#endif
} }
}; };
@ -546,18 +547,16 @@ struct rem_port
void setRecvState(const RecvQueState& rs) void setRecvState(const RecvQueState& rs)
{ {
#ifdef SUPERSERVER
if (rs.save_qoffset > 0 && (rs.save_qoffset != port_qoffset)) if (rs.save_qoffset > 0 && (rs.save_qoffset != port_qoffset))
{ {
Firebird::Array<char>& q = (*port_queue)[rs.save_qoffset - 1]; Firebird::Array<char>& q = (*port_queue)[rs.save_qoffset - 1];
memcpy(port_receive.x_base, q.begin(), q.getCount()); memcpy(port_receive.x_base, q.begin(), q.getCount());
} }
port_qoffset = rs.save_qoffset; port_qoffset = rs.save_qoffset;
#endif
port_receive.x_private = port_receive.x_base + rs.save_private; port_receive.x_private = port_receive.x_base + rs.save_private;
port_receive.x_handy = rs.save_handy; port_receive.x_handy = rs.save_handy;
} }
#endif // REM_SERVER
/* TMN: The following member functions are conceptually private /* TMN: The following member functions are conceptually private
* to server.cpp and should be _made_ private in due time! * to server.cpp and should be _made_ private in due time!
@ -604,17 +603,17 @@ struct rem_port
}; };
// port_flags // port_flags
const USHORT PORT_symmetric = 1; // Server/client archiectures are symmetic const USHORT PORT_symmetric = 0x0001; // Server/client archiectures are symmetic
const USHORT PORT_rpc = 2; // Protocol is remote procedure call const USHORT PORT_rpc = 0x0002; // Protocol is remote procedure call
const USHORT PORT_async = 4; // Port is asynchronous channel for events const USHORT PORT_async = 0x0004; // Port is asynchronous channel for events
const USHORT PORT_no_oob = 8; // Don't send out of band data const USHORT PORT_no_oob = 0x0008; // Don't send out of band data
const USHORT PORT_disconnect = 16; // Disconnect is in progress const USHORT PORT_disconnect = 0x0010; // Disconnect is in progress
// This is set only in inet.cpp but never tested // This is set only in inet.cpp but never tested
const USHORT PORT_not_trusted = 32; // Connection is from an untrusted node const USHORT PORT_not_trusted = 0x0020; // Connection is from an untrusted node
const USHORT PORT_dummy_pckt_set= 64; // A dummy packet interval is set const USHORT PORT_dummy_pckt_set= 0x0040; // A dummy packet interval is set
const USHORT PORT_partial_data = 128; // Physical packet doesn't contain all API packet const USHORT PORT_partial_data = 0x0080; // Physical packet doesn't contain all API packet
const USHORT PORT_lazy = 256; // Deferred operations are allowed const USHORT PORT_lazy = 0x0100; // Deferred operations are allowed
const USHORT PORT_busy = 512; // Disable receive -- port is busy now const USHORT PORT_server = 0x0200; // Server (not client) port
/* Queuing structure for Client batch fetches */ /* Queuing structure for Client batch fetches */

View File

@ -34,7 +34,7 @@ extern "C" {
void SRVR_main(rem_port*, USHORT); void SRVR_main(rem_port*, USHORT);
void SRVR_multi_thread(rem_port*, USHORT); void SRVR_multi_thread(rem_port*, USHORT);
void SRVR_shutdown(); int SRVR_shutdown();
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"

File diff suppressed because it is too large Load Diff

View File

@ -39,7 +39,6 @@
#include "../jrd/gds_proto.h" #include "../jrd/gds_proto.h"
#include "../jrd/isc_proto.h" #include "../jrd/isc_proto.h"
#include "../jrd/sch_proto.h" #include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/classes/init.h" #include "../common/classes/init.h"
#include "../common/classes/fb_string.h" #include "../common/classes/fb_string.h"
#include "../common/config/config.h" #include "../common/config/config.h"
@ -132,7 +131,7 @@ static char xnet_endpoint[BUFFER_TINY] = "";
static bool xnet_initialized = false; static bool xnet_initialized = false;
static bool xnet_shutdown = false; static bool xnet_shutdown = false;
static bool xnet_mutex_ready = false; static Firebird::GlobalPtr<Firebird::Mutex> xnet_mutex;
static bool connect_init(); static bool connect_init();
static void connect_fini(); static void connect_fini();
@ -159,23 +158,6 @@ inline void make_event_name(char* buffer, size_t size, const char* format, ULONG
fb_utils::snprintf(buffer, size, format, xnet_endpoint, arg1, arg2, arg3); fb_utils::snprintf(buffer, size, format, xnet_endpoint, arg1, arg2, arg3);
} }
static Firebird::GlobalPtr<Firebird::Mutex> xnet_mutex;
inline void XNET_LOCK() {
if (!xnet_shutdown)
{
THREAD_EXIT();
}
xnet_mutex->enter();
if (!xnet_shutdown)
{
THREAD_ENTER();
}
}
inline void XNET_UNLOCK() {
xnet_mutex->leave();
}
static int xnet_error(rem_port*, ISC_STATUS, int); static int xnet_error(rem_port*, ISC_STATUS, int);
@ -668,6 +650,13 @@ static rem_port* alloc_port(rem_port* parent,
port->port_buff_size = send_length; port->port_buff_size = send_length;
port->port_status_vector = NULL; port->port_status_vector = NULL;
port->port_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_sync->addRef();
#ifdef REM_SERVER
port->port_que_sync = FB_NEW(*getDefaultMemoryPool()) Firebird::RefMutex();
port->port_que_sync->addRef();
#endif
xdrxnet_create(&port->port_send, port, send_buffer, send_length, XDR_ENCODE); xdrxnet_create(&port->port_send, port, send_buffer, send_length, XDR_ENCODE);
xdrxnet_create(&port->port_receive, port, receive_buffer, 0, XDR_DECODE); xdrxnet_create(&port->port_receive, port, receive_buffer, 0, XDR_DECODE);
@ -982,7 +971,7 @@ static void cleanup_comm(XCC xcc)
if (xpm) { if (xpm) {
xpm->xpm_count--; xpm->xpm_count--;
XNET_LOCK(); Firebird::MutexLockGuard guard(xnet_mutex);
if (!xpm->xpm_count && global_client_maps) { if (!xpm->xpm_count && global_client_maps) {
UnmapViewOfFile(xpm->xpm_address); UnmapViewOfFile(xpm->xpm_address);
@ -1004,8 +993,6 @@ static void cleanup_comm(XCC xcc)
} }
ALLR_free(xpm); ALLR_free(xpm);
} }
XNET_UNLOCK();
} }
} }
@ -1056,6 +1043,11 @@ static void cleanup_port(rem_port* port)
ALLR_free(port->port_address_str); ALLR_free(port->port_address_str);
} }
port->port_sync->release();
#ifdef REM_SERVER
port->port_que_sync->release();
#endif
ALLR_free(port); ALLR_free(port);
} }
@ -1087,7 +1079,10 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
status_vector[1] = isc_unavailable; status_vector[1] = isc_unavailable;
status_vector[2] = isc_arg_end; status_vector[2] = isc_arg_end;
XNET_LOCK(); XNET_RESPONSE response;
{ // xnet_mutex scope
Firebird::MutexLockGuard guard(xnet_mutex);
// First, try to connect using default kernel namespace. // First, try to connect using default kernel namespace.
// This should work on Win9X, NT4 and on later OS when server is running // This should work on Win9X, NT4 and on later OS when server is running
@ -1101,7 +1096,6 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
fb_utils::snprintf(xnet_endpoint, sizeof(xnet_endpoint), "Global\\%s", Config::getIpcName()); fb_utils::snprintf(xnet_endpoint, sizeof(xnet_endpoint), "Global\\%s", Config::getIpcName());
if (!connect_init()) { if (!connect_init()) {
XNET_UNLOCK();
return NULL; return NULL;
} }
} }
@ -1111,7 +1105,6 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
if (WaitForSingleObject(xnet_connect_mutex, XNET_CONNECT_TIMEOUT) != WAIT_OBJECT_0) if (WaitForSingleObject(xnet_connect_mutex, XNET_CONNECT_TIMEOUT) != WAIT_OBJECT_0)
{ {
connect_fini(); connect_fini();
XNET_UNLOCK();
return NULL; return NULL;
} }
@ -1131,16 +1124,13 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
{ {
ReleaseMutex(xnet_connect_mutex); ReleaseMutex(xnet_connect_mutex);
connect_fini(); connect_fini();
XNET_UNLOCK();
return NULL; return NULL;
} }
XNET_RESPONSE response;
memcpy(&response, xnet_connect_map, XNET_CONNECT_RESPONZE_SIZE); memcpy(&response, xnet_connect_map, XNET_CONNECT_RESPONZE_SIZE);
ReleaseMutex(xnet_connect_mutex); ReleaseMutex(xnet_connect_mutex);
connect_fini(); connect_fini();
} // xnet_mutex scope
XNET_UNLOCK();
if (response.map_num == XNET_INVALID_MAP_NUM) { if (response.map_num == XNET_INVALID_MAP_NUM) {
xnet_log_error("Server failed to respond on connect request"); xnet_log_error("Server failed to respond on connect request");
@ -1163,9 +1153,8 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
try { try {
XNET_LOCK(); { // xnet_mutex scope
Firebird::MutexLockGuard guard(xnet_mutex);
try {
// see if area is already mapped for this client // see if area is already mapped for this client
@ -1206,14 +1195,7 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
xpm->xpm_timestamp = timestamp; xpm->xpm_timestamp = timestamp;
xpm->xpm_flags = 0; xpm->xpm_flags = 0;
} }
} // xnet_mutex scope
}
catch (const Firebird::Exception&) {
XNET_UNLOCK();
throw;
}
XNET_UNLOCK();
// there's no thread structure, so make one // there's no thread structure, so make one
xcc = (XCC) ALLR_alloc(sizeof(struct xcc)); xcc = (XCC) ALLR_alloc(sizeof(struct xcc));
@ -1366,9 +1348,7 @@ static rem_port* connect_server(ISC_STATUS* status_vector, USHORT flag)
while (!xnet_shutdown) { while (!xnet_shutdown) {
THREAD_EXIT();
const DWORD wait_res = WaitForSingleObject(xnet_connect_event, INFINITE); const DWORD wait_res = WaitForSingleObject(xnet_connect_event, INFINITE);
THREAD_ENTER();
if (wait_res != WAIT_OBJECT_0) { if (wait_res != WAIT_OBJECT_0) {
xnet_log_error("WaitForSingleObject() failed"); xnet_log_error("WaitForSingleObject() failed");
@ -1596,7 +1576,7 @@ static void server_shutdown(rem_port* port)
// mark all mapped areas connected to server with dead_proc_id // mark all mapped areas connected to server with dead_proc_id
XNET_LOCK(); Firebird::MutexLockGuard guard(xnet_mutex);
for (xpm = global_client_maps; xpm; xpm = xpm->xpm_next) for (xpm = global_client_maps; xpm; xpm = xpm->xpm_next)
{ {
@ -1608,8 +1588,6 @@ static void server_shutdown(rem_port* port)
xpm->xpm_address = NULL; xpm->xpm_address = NULL;
} }
} }
XNET_UNLOCK();
} }
} }
#endif // SUPERCLIENT #endif // SUPERCLIENT
@ -1878,25 +1856,20 @@ static bool_t xnet_putbytes(XDR* xdrs, const SCHAR* buff, u_int count)
return FALSE; return FALSE;
} }
#endif #endif
THREAD_EXIT();
const DWORD wait_result = const DWORD wait_result =
WaitForSingleObject(xcc->xcc_event_send_channel_empted, WaitForSingleObject(xcc->xcc_event_send_channel_empted,
XNET_SEND_WAIT_TIMEOUT); XNET_SEND_WAIT_TIMEOUT);
if (wait_result == WAIT_OBJECT_0) { if (wait_result == WAIT_OBJECT_0) {
THREAD_ENTER();
break; break;
} }
if (wait_result == WAIT_TIMEOUT) if (wait_result == WAIT_TIMEOUT)
{ {
// Check whether another side is alive // Check whether another side is alive
if (WaitForSingleObject(xcc->xcc_proc_h, 1) == WAIT_TIMEOUT) { if (WaitForSingleObject(xcc->xcc_proc_h, 1) == WAIT_TIMEOUT) {
THREAD_ENTER();
continue; // another side is alive continue; // another side is alive
} }
THREAD_ENTER();
// Another side is dead or something bad has happened // Another side is dead or something bad has happened
#ifdef SUPERCLIENT #ifdef SUPERCLIENT
server_shutdown(port); server_shutdown(port);
@ -1907,7 +1880,6 @@ static bool_t xnet_putbytes(XDR* xdrs, const SCHAR* buff, u_int count)
return FALSE; return FALSE;
} }
THREAD_ENTER();
xnet_error(port, isc_net_write_err, ERRNO); xnet_error(port, isc_net_write_err, ERRNO);
return FALSE; // a non-timeout result is an error return FALSE; // a non-timeout result is an error
} }
@ -1992,15 +1964,12 @@ static bool_t xnet_read(XDR * xdrs)
return FALSE; return FALSE;
} }
#endif #endif
THREAD_EXIT();
const DWORD wait_result = const DWORD wait_result =
WaitForSingleObject(xcc->xcc_event_recv_channel_filled, WaitForSingleObject(xcc->xcc_event_recv_channel_filled,
XNET_RECV_WAIT_TIMEOUT); XNET_RECV_WAIT_TIMEOUT);
if (wait_result == WAIT_OBJECT_0) if (wait_result == WAIT_OBJECT_0)
{ {
THREAD_ENTER();
// Client has written some data for us (server) to read // Client has written some data for us (server) to read
xdrs->x_handy = xch->xch_length; xdrs->x_handy = xch->xch_length;
xdrs->x_private = xdrs->x_base; xdrs->x_private = xdrs->x_base;
@ -2010,11 +1979,9 @@ static bool_t xnet_read(XDR * xdrs)
{ {
// Check if another side is alive // Check if another side is alive
if (WaitForSingleObject(xcc->xcc_proc_h, 1) == WAIT_TIMEOUT) { if (WaitForSingleObject(xcc->xcc_proc_h, 1) == WAIT_TIMEOUT) {
THREAD_ENTER();
continue; // another side is alive continue; // another side is alive
} }
THREAD_ENTER();
// Another side is dead or something bad has happened // Another side is dead or something bad has happened
#ifdef SUPERCLIENT #ifdef SUPERCLIENT
server_shutdown(port); server_shutdown(port);
@ -2024,7 +1991,7 @@ static bool_t xnet_read(XDR * xdrs)
#endif #endif
return FALSE; return FALSE;
} }
THREAD_ENTER();
xnet_error(port, isc_net_read_err, ERRNO); xnet_error(port, isc_net_read_err, ERRNO);
return FALSE; // a non-timeout result is an error return FALSE; // a non-timeout result is an error
} }
@ -2101,7 +2068,7 @@ void release_all()
connect_fini(); connect_fini();
#endif #endif
XNET_LOCK(); Firebird::MutexLockGuard guard(xnet_mutex);
// release all map stuf left not released by broken ports // release all map stuf left not released by broken ports
@ -2114,9 +2081,6 @@ void release_all()
} }
global_client_maps = NULL; global_client_maps = NULL;
XNET_UNLOCK();
xnet_initialized = false; xnet_initialized = false;
} }
@ -2199,12 +2163,12 @@ static XPM make_xpm(ULONG map_number, ULONG timestamp)
} }
xpm->xpm_flags = 0; xpm->xpm_flags = 0;
XNET_LOCK(); {
Firebird::MutexLockGuard guard(xnet_mutex);
xpm->xpm_next = global_client_maps; xpm->xpm_next = global_client_maps;
global_client_maps = xpm; global_client_maps = xpm;
}
XNET_UNLOCK();
return xpm; return xpm;
} }
@ -2327,7 +2291,8 @@ static XPM get_free_slot(ULONG* map_num, ULONG* slot_num, ULONG* timestamp)
XPM xpm = NULL; XPM xpm = NULL;
ULONG i = 0, j = 0; ULONG i = 0, j = 0;
XNET_LOCK(); { // xnet_mutex scope
Firebird::MutexLockGuard guard(xnet_mutex);
// go through list of maps // go through list of maps
@ -2349,8 +2314,7 @@ static XPM get_free_slot(ULONG* map_num, ULONG* slot_num, ULONG* timestamp)
} }
j++; j++;
} }
} // xnet_mutex scope
XNET_UNLOCK();
// if the mapped file structure has not yet been initialized, // if the mapped file structure has not yet been initialized,
// make one now // make one now