8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 03:23:04 +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 "gen/iberror.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"

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -34,7 +34,6 @@
#include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../jrd/jrd_proto.h"
#include "../jrd/why_proto.h"
#include "../common/classes/init.h"
#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);
fb_shutdown(NULL, SHUTDOWN_TIMEOUT);
SRVR_shutdown();
report_status(SERVICE_STOPPED, last_error, 0, 0);
}

View File

@ -98,7 +98,6 @@
#include "../remote/xnet_proto.h"
#include "../jrd/gds_proto.h"
#include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../jrd/isc_proto.h"
#include "../jrd/jrd_proto.h"
#include "../jrd/os/isc_i_proto.h"
@ -141,6 +140,10 @@ int WINAPI WinMain(HINSTANCE 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
try
{
@ -185,12 +188,6 @@ int WINAPI WinMain(HINSTANCE hThisInst,
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
// get priority class from the config file
int priority = Config::getProcessPriorityLevel();
@ -213,10 +210,7 @@ int WINAPI WinMain(HINSTANCE hThisInst,
Setup sig_mutex for the process
*/
ISC_signal_init();
#ifdef SUPERSERVER
ISC_enter();
#endif
int nReturnValue = 0;
ISC_STATUS_ARRAY status_vector;
@ -224,14 +218,14 @@ int WINAPI WinMain(HINSTANCE hThisInst,
if (connection_handle != INVALID_HANDLE_VALUE)
{
rem_port* port = 0;
THREAD_ENTER();
if (server_flag & SRVR_inet)
port = INET_reconnect(connection_handle, status_vector);
else if (server_flag & SRVR_wnet)
port = WNET_reconnect(connection_handle, status_vector);
else if (server_flag & SRVR_xnet)
port = XNET_reconnect((ULONG) connection_handle, status_vector);
THREAD_EXIT();
if (port) {
service_connection(port);
}
@ -264,19 +258,7 @@ int WINAPI WinMain(HINSTANCE hThisInst,
}
else
{
if (server_flag & SRVR_inet) {
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);
}
start_connections_thread(0);
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;
while (true)
{
THREAD_ENTER();
rem_port* port =
INET_connect(protocol_inet, NULL, status_vector, server_flag, 0);
THREAD_EXIT();
rem_port* port = INET_connect(protocol_inet, NULL, status_vector, server_flag, 0);
if (!port) {
gds__log_status(0, status_vector);
break;
@ -354,8 +334,7 @@ static THREAD_ENTRY_DECLARE inet_connect_wait_thread(THREAD_ENTRY_PARAM)
break;
}
else {
gds__thread_start(process_connection_thread, port,
THREAD_medium, 0, 0);
gds__thread_start(process_connection_thread, port, THREAD_medium, 0, 0);
}
}
@ -385,10 +364,8 @@ static THREAD_ENTRY_DECLARE wnet_connect_wait_thread(THREAD_ENTRY_PARAM)
ISC_STATUS_ARRAY status_vector;
while (true)
{
THREAD_ENTER();
rem_port* port =
WNET_connect(protocol_wnet, NULL, status_vector, server_flag);
THREAD_EXIT();
rem_port* port = WNET_connect(protocol_wnet, NULL, status_vector, server_flag);
if (!port) {
if (status_vector[1] != isc_io_error ||
status_vector[6] != isc_arg_win32 ||
@ -398,8 +375,7 @@ static THREAD_ENTRY_DECLARE wnet_connect_wait_thread(THREAD_ENTRY_PARAM)
}
break;
}
gds__thread_start(process_connection_thread, port,
THREAD_medium, 0, 0);
gds__thread_start(process_connection_thread, port, THREAD_medium, 0, 0);
}
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;
while (true)
{
THREAD_ENTER();
rem_port* port =
XNET_connect(NULL, NULL, status_vector, server_flag);
THREAD_EXIT();
rem_port* port = XNET_connect(NULL, NULL, status_vector, server_flag);
if (!port) {
gds__log_status(0, status_vector);
break;
}
gds__thread_start(process_connection_thread, port,
THREAD_medium, 0, 0);
gds__thread_start(process_connection_thread, port, THREAD_medium, 0, 0);
}
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) {
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;
}

View File

@ -39,7 +39,6 @@
#include "../remote/os/win32/window_proto.h"
#include "../remote/os/win32/propty_proto.h"
#include "../jrd/gds_proto.h"
#include "../jrd/why_proto.h"
#include "../remote/os/win32/window.h"
#include "../jrd/isc_proto.h"
@ -52,9 +51,10 @@
#include "../common/config/config.h"
HWND hPSDlg = NULL;
static HWND hPSDlg = NULL;
static HINSTANCE hInstance = NULL;
static USHORT usServerFlags;
static HWND hMainWnd = NULL;
// Static functions to be called from this file only.
static void GetDriveLetter(ULONG, char pchBuf[DRV_STRINGLEN]);
@ -66,6 +66,7 @@ static BOOL CanEndServer(HWND, bool);
// Window Procedure
LRESULT CALLBACK WindowFunc(HWND, UINT, WPARAM, LPARAM);
static int fb_shutdown_cb();
int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask)
{
@ -90,6 +91,8 @@ int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask)
hInstance = hThisInst;
usServerFlags = usServerFlagMask;
fb_shutdown_callback(0, fb_shutdown_cb, fb_shut_postproviders);
/* initialize main window */
WNDCLASS wcl;
@ -115,7 +118,7 @@ int WINDOW_main( HINSTANCE hThisInst, int nWndMode, USHORT usServerFlagMask)
return 0;
}
hWnd = CreateWindowEx(0,
hMainWnd = hWnd = CreateWindowEx(0,
szClassName,
APP_NAME,
WS_DLGFRAME | WS_SYSMENU | WS_MINIMIZEBOX,
@ -214,8 +217,7 @@ LRESULT CALLBACK WindowFunc(HWND hWnd,
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
}
fb_shutdown(NULL, 0);
SRVR_shutdown();
DestroyWindow(hWnd);
//DestroyWindow(hWnd);
}
}
break;
@ -427,8 +429,7 @@ LRESULT CALLBACK WindowFunc(HWND hWnd,
}
fb_shutdown(NULL, 0);
SRVR_shutdown();
PostMessage(hWnd, WM_DESTROY, 0, 0);
//DestroyWindow(hWnd);
return TRUE;
}
/* 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));
GetDriveLetter(pdbcv->dbcv_unitmask, szDrives);
MessageBox(hWnd, tmp, szDrives, MB_OK | MB_ICONHAND);
fb_shutdown(NULL, 0);
SRVR_shutdown();
PostMessage(hWnd, WM_DESTROY, 0, 0);
fb_shutdown(NULL, 0);
}
return TRUE;
@ -539,3 +539,11 @@ BOOL CanEndServer(HWND hWnd, bool bSysExit)
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_f_proto.h"
#include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/config/config.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* SERVER_PIPE_SUFFIX = "server";
const char* EVENT_PIPE_SUFFIX = "event";
Firebird::AtomicCounter event_counter;
static int accept_connection(rem_port*, P_CNCT *);
@ -335,7 +335,6 @@ rem_port* WNET_connect(const TEXT* name,
if (packet)
{
THREAD_EXIT();
while (true) {
port->port_handle = CreateFile(port->port_connection->str_data,
GENERIC_WRITE | GENERIC_READ,
@ -345,14 +344,12 @@ rem_port* WNET_connect(const TEXT* name,
}
const ISC_STATUS status = GetLastError();
if (status != ERROR_PIPE_BUSY) {
THREAD_ENTER();
wnet_error(port, "CreateFile", isc_net_connect_err, status);
disconnect(port);
return NULL;
}
WaitNamedPipe(port->port_connection->str_data, 3000L);
}
THREAD_ENTER();
send_full(port, packet);
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 */
LPSECURITY_ATTRIBUTES security_attr = ISC_get_security_desc();
THREAD_EXIT();
while (true)
{
@ -379,7 +375,6 @@ rem_port* WNET_connect(const TEXT* name,
// TMN: The check for GetLastError() is redundant.
// This code should NEVER be called if not running on NT,
// since Win9x does not support the server side of named pipes!
THREAD_ENTER();
wnet_error(port, "CreateNamedPipe", isc_net_connect_listen_err,
ERRNO);
disconnect(port);
@ -389,7 +384,6 @@ rem_port* WNET_connect(const TEXT* name,
if (!ConnectNamedPipe(port->port_handle, 0) &&
GetLastError() != ERROR_PIPE_CONNECTED)
{
THREAD_ENTER();
wnet_error(port, "ConnectNamedPipe", isc_net_connect_err, ERRNO);
disconnect(port);
return NULL;
@ -397,7 +391,6 @@ rem_port* WNET_connect(const TEXT* name,
if (flag & (SRVR_debug | SRVR_multi_client))
{
THREAD_ENTER();
port->port_server_flags |= SRVR_server;
if (flag & SRVR_multi_client)
{
@ -588,6 +581,13 @@ static rem_port* alloc_port( rem_port* parent)
port->port_request = aux_request;
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,
&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 =
make_pipe_name(port->port_connection->str_data, EVENT_PIPE_SUFFIX, p);
THREAD_EXIT();
while (true) {
new_port->port_handle =
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;
const ISC_STATUS status = GetLastError();
if (status != ERROR_PIPE_BUSY) {
THREAD_ENTER();
return (rem_port*) wnet_error(new_port, "CreateFile",
isc_net_event_connect_err, status);
}
WaitNamedPipe(new_port->port_connection->str_data, 3000L);
}
THREAD_ENTER();
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
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);
new_port->port_server_flags = vport->port_server_flags;
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);
LPSECURITY_ATTRIBUTES security_attr = ISC_get_security_desc();
THREAD_EXIT();
new_port->port_handle =
CreateNamedPipe(new_port->port_connection->str_data,
PIPE_ACCESS_DUPLEX,
@ -712,7 +709,7 @@ static rem_port* aux_request( rem_port* vport, PACKET* packet)
MAX_DATA,
0,
security_attr);
THREAD_ENTER();
if (new_port->port_handle == INVALID_HANDLE_VALUE) {
wnet_error(new_port, "CreateNamedPipe", isc_net_event_listen_err,
ERRNO);
@ -827,6 +824,11 @@ static void cleanup_port( rem_port* port)
ALLR_free(port->port_packet_vector);
#endif
port->port_sync->release();
#ifdef REM_SERVER
port->port_que_sync->release();
#endif
ALLR_free(port);
return;
}
@ -1453,15 +1455,12 @@ static int packet_receive(
**************************************/
DWORD n = 0;
THREAD_EXIT();
const USHORT status =
ReadFile(port->port_handle, buffer, buffer_length, &n, NULL);
THREAD_ENTER();
const USHORT status = ReadFile(port->port_handle, buffer, buffer_length, &n, NULL);
if (!status && GetLastError() != ERROR_BROKEN_PIPE)
return wnet_error(port, "ReadFile", isc_net_read_err, ERRNO);
if (!n)
return wnet_error(port, "ReadFile end-of-file", isc_net_read_err,
ERRNO);
return wnet_error(port, "ReadFile end-of-file", isc_net_read_err, ERRNO);
#if defined(DEBUG) && defined(WNET_trace)
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 DWORD length = buffer_length;
THREAD_EXIT();
DWORD n;
const USHORT status = WriteFile(port->port_handle, data, length, &n, NULL);
THREAD_ENTER();
if (!status)
return wnet_error(port, "WriteFile", isc_net_write_err, ERRNO);
if (n != length)

View File

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

View File

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

View File

@ -34,7 +34,7 @@ extern "C" {
void SRVR_main(rem_port*, USHORT);
void SRVR_multi_thread(rem_port*, USHORT);
void SRVR_shutdown();
int SRVR_shutdown();
#ifdef __cplusplus
} // 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/isc_proto.h"
#include "../jrd/sch_proto.h"
#include "../jrd/thread_proto.h"
#include "../common/classes/init.h"
#include "../common/classes/fb_string.h"
#include "../common/config/config.h"
@ -132,7 +131,7 @@ static char xnet_endpoint[BUFFER_TINY] = "";
static bool xnet_initialized = false;
static bool xnet_shutdown = false;
static bool xnet_mutex_ready = false;
static Firebird::GlobalPtr<Firebird::Mutex> xnet_mutex;
static bool connect_init();
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);
}
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);
@ -668,6 +650,13 @@ static rem_port* alloc_port(rem_port* parent,
port->port_buff_size = send_length;
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_receive, port, receive_buffer, 0, XDR_DECODE);
@ -982,7 +971,7 @@ static void cleanup_comm(XCC xcc)
if (xpm) {
xpm->xpm_count--;
XNET_LOCK();
Firebird::MutexLockGuard guard(xnet_mutex);
if (!xpm->xpm_count && global_client_maps) {
UnmapViewOfFile(xpm->xpm_address);
@ -1004,8 +993,6 @@ static void cleanup_comm(XCC xcc)
}
ALLR_free(xpm);
}
XNET_UNLOCK();
}
}
@ -1056,6 +1043,11 @@ static void cleanup_port(rem_port* port)
ALLR_free(port->port_address_str);
}
port->port_sync->release();
#ifdef REM_SERVER
port->port_que_sync->release();
#endif
ALLR_free(port);
}
@ -1087,60 +1079,58 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
status_vector[1] = isc_unavailable;
status_vector[2] = isc_arg_end;
XNET_LOCK();
XNET_RESPONSE response;
// First, try to connect using default kernel namespace.
// This should work on Win9X, NT4 and on later OS when server is running
// under restricted account in the same session as the client
fb_utils::copy_terminate(xnet_endpoint, Config::getIpcName(), sizeof(xnet_endpoint));
{ // xnet_mutex scope
Firebird::MutexLockGuard guard(xnet_mutex);
if (!connect_init()) {
// The client may not have permissions to create global objects,
// but still be able to connect to a local server that has such permissions.
// This is why we try to connect using Global\ namespace unconditionally
fb_utils::snprintf(xnet_endpoint, sizeof(xnet_endpoint), "Global\\%s", Config::getIpcName());
// First, try to connect using default kernel namespace.
// This should work on Win9X, NT4 and on later OS when server is running
// under restricted account in the same session as the client
fb_utils::copy_terminate(xnet_endpoint, Config::getIpcName(), sizeof(xnet_endpoint));
if (!connect_init()) {
XNET_UNLOCK();
// The client may not have permissions to create global objects,
// but still be able to connect to a local server that has such permissions.
// This is why we try to connect using Global\ namespace unconditionally
fb_utils::snprintf(xnet_endpoint, sizeof(xnet_endpoint), "Global\\%s", Config::getIpcName());
if (!connect_init()) {
return NULL;
}
}
// waiting for XNET connect lock to release
if (WaitForSingleObject(xnet_connect_mutex, XNET_CONNECT_TIMEOUT) != WAIT_OBJECT_0)
{
connect_fini();
return NULL;
}
}
// waiting for XNET connect lock to release
// writing connect request
if (WaitForSingleObject(xnet_connect_mutex, XNET_CONNECT_TIMEOUT) != WAIT_OBJECT_0)
{
connect_fini();
XNET_UNLOCK();
return NULL;
}
// mark connect area with XNET_INVALID_MAP_NUM to
// detect server faults on response
// writing connect request
PXNET_RESPONSE(xnet_connect_map)->map_num = XNET_INVALID_MAP_NUM;
PXNET_RESPONSE(xnet_connect_map)->proc_id = current_process_id;
// mark connect area with XNET_INVALID_MAP_NUM to
// detect server faults on response
SetEvent(xnet_connect_event);
PXNET_RESPONSE(xnet_connect_map)->map_num = XNET_INVALID_MAP_NUM;
PXNET_RESPONSE(xnet_connect_map)->proc_id = current_process_id;
// waiting for server response
SetEvent(xnet_connect_event);
if (WaitForSingleObject(xnet_response_event, XNET_CONNECT_TIMEOUT) != WAIT_OBJECT_0)
{
ReleaseMutex(xnet_connect_mutex);
connect_fini();
return NULL;
}
// waiting for server response
if (WaitForSingleObject(xnet_response_event, XNET_CONNECT_TIMEOUT) != WAIT_OBJECT_0)
{
memcpy(&response, xnet_connect_map, XNET_CONNECT_RESPONZE_SIZE);
ReleaseMutex(xnet_connect_mutex);
connect_fini();
XNET_UNLOCK();
return NULL;
}
XNET_RESPONSE response;
memcpy(&response, xnet_connect_map, XNET_CONNECT_RESPONZE_SIZE);
ReleaseMutex(xnet_connect_mutex);
connect_fini();
XNET_UNLOCK();
} // xnet_mutex scope
if (response.map_num == XNET_INVALID_MAP_NUM) {
xnet_log_error("Server failed to respond on connect request");
@ -1163,57 +1153,49 @@ static rem_port* connect_client(PACKET* packet, ISC_STATUS* status_vector)
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
for (xpm = global_client_maps; xpm; xpm = xpm->xpm_next) {
if (xpm->xpm_number == map_num &&
xpm->xpm_timestamp == timestamp &&
!(xpm->xpm_flags & XPMF_SERVER_SHUTDOWN))
{
break;
}
}
if (!xpm) {
// Area hasn't been mapped. Open new file mapping.
make_map_name(name_buffer, sizeof(name_buffer), XNET_MAPPED_FILE_NAME,
map_num, timestamp);
file_handle = OpenFileMapping(FILE_MAP_WRITE, FALSE, name_buffer);
if (!file_handle) {
Firebird::system_call_failed::raise("OpenFileMapping");
for (xpm = global_client_maps; xpm; xpm = xpm->xpm_next) {
if (xpm->xpm_number == map_num &&
xpm->xpm_timestamp == timestamp &&
!(xpm->xpm_flags & XPMF_SERVER_SHUTDOWN))
{
break;
}
}
mapped_address = MapViewOfFile(file_handle, FILE_MAP_WRITE, 0L, 0L,
XPS_MAPPED_SIZE(global_slots_per_map, global_pages_per_slot));
if (!mapped_address) {
Firebird::system_call_failed::raise("MapViewOfFile");
if (!xpm) {
// Area hasn't been mapped. Open new file mapping.
make_map_name(name_buffer, sizeof(name_buffer), XNET_MAPPED_FILE_NAME,
map_num, timestamp);
file_handle = OpenFileMapping(FILE_MAP_WRITE, FALSE, name_buffer);
if (!file_handle) {
Firebird::system_call_failed::raise("OpenFileMapping");
}
mapped_address = MapViewOfFile(file_handle, FILE_MAP_WRITE, 0L, 0L,
XPS_MAPPED_SIZE(global_slots_per_map, global_pages_per_slot));
if (!mapped_address) {
Firebird::system_call_failed::raise("MapViewOfFile");
}
xpm = (XPM) ALLR_alloc(sizeof(struct xpm));
xpm->xpm_next = global_client_maps;
global_client_maps = xpm;
xpm->xpm_count = 0;
xpm->xpm_number = map_num;
xpm->xpm_handle = file_handle;
xpm->xpm_address = mapped_address;
xpm->xpm_timestamp = timestamp;
xpm->xpm_flags = 0;
}
xpm = (XPM) ALLR_alloc(sizeof(struct xpm));
xpm->xpm_next = global_client_maps;
global_client_maps = xpm;
xpm->xpm_count = 0;
xpm->xpm_number = map_num;
xpm->xpm_handle = file_handle;
xpm->xpm_address = mapped_address;
xpm->xpm_timestamp = timestamp;
xpm->xpm_flags = 0;
}
}
catch (const Firebird::Exception&) {
XNET_UNLOCK();
throw;
}
XNET_UNLOCK();
} // xnet_mutex scope
// there's no thread structure, so make one
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) {
THREAD_EXIT();
const DWORD wait_res = WaitForSingleObject(xnet_connect_event, INFINITE);
THREAD_ENTER();
if (wait_res != WAIT_OBJECT_0) {
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
XNET_LOCK();
Firebird::MutexLockGuard guard(xnet_mutex);
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;
}
}
XNET_UNLOCK();
}
}
#endif // SUPERCLIENT
@ -1878,25 +1856,20 @@ static bool_t xnet_putbytes(XDR* xdrs, const SCHAR* buff, u_int count)
return FALSE;
}
#endif
THREAD_EXIT();
const DWORD wait_result =
WaitForSingleObject(xcc->xcc_event_send_channel_empted,
XNET_SEND_WAIT_TIMEOUT);
if (wait_result == WAIT_OBJECT_0) {
THREAD_ENTER();
break;
}
if (wait_result == WAIT_TIMEOUT)
{
// Check whether another side is alive
if (WaitForSingleObject(xcc->xcc_proc_h, 1) == WAIT_TIMEOUT) {
THREAD_ENTER();
continue; // another side is alive
}
THREAD_ENTER();
// Another side is dead or something bad has happened
#ifdef SUPERCLIENT
server_shutdown(port);
@ -1907,7 +1880,6 @@ static bool_t xnet_putbytes(XDR* xdrs, const SCHAR* buff, u_int count)
return FALSE;
}
THREAD_ENTER();
xnet_error(port, isc_net_write_err, ERRNO);
return FALSE; // a non-timeout result is an error
}
@ -1992,15 +1964,12 @@ static bool_t xnet_read(XDR * xdrs)
return FALSE;
}
#endif
THREAD_EXIT();
const DWORD wait_result =
WaitForSingleObject(xcc->xcc_event_recv_channel_filled,
XNET_RECV_WAIT_TIMEOUT);
if (wait_result == WAIT_OBJECT_0)
{
THREAD_ENTER();
// Client has written some data for us (server) to read
xdrs->x_handy = xch->xch_length;
xdrs->x_private = xdrs->x_base;
@ -2010,11 +1979,9 @@ static bool_t xnet_read(XDR * xdrs)
{
// Check if another side is alive
if (WaitForSingleObject(xcc->xcc_proc_h, 1) == WAIT_TIMEOUT) {
THREAD_ENTER();
continue; // another side is alive
}
THREAD_ENTER();
// Another side is dead or something bad has happened
#ifdef SUPERCLIENT
server_shutdown(port);
@ -2024,7 +1991,7 @@ static bool_t xnet_read(XDR * xdrs)
#endif
return FALSE;
}
THREAD_ENTER();
xnet_error(port, isc_net_read_err, ERRNO);
return FALSE; // a non-timeout result is an error
}
@ -2101,7 +2068,7 @@ void release_all()
connect_fini();
#endif
XNET_LOCK();
Firebird::MutexLockGuard guard(xnet_mutex);
// release all map stuf left not released by broken ports
@ -2114,9 +2081,6 @@ void release_all()
}
global_client_maps = NULL;
XNET_UNLOCK();
xnet_initialized = false;
}
@ -2199,12 +2163,12 @@ static XPM make_xpm(ULONG map_number, ULONG timestamp)
}
xpm->xpm_flags = 0;
XNET_LOCK();
{
Firebird::MutexLockGuard guard(xnet_mutex);
xpm->xpm_next = global_client_maps;
global_client_maps = xpm;
XNET_UNLOCK();
xpm->xpm_next = global_client_maps;
global_client_maps = xpm;
}
return xpm;
}
@ -2327,30 +2291,30 @@ static XPM get_free_slot(ULONG* map_num, ULONG* slot_num, ULONG* timestamp)
XPM xpm = NULL;
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
for (xpm = global_client_maps; xpm; xpm = xpm->xpm_next) {
for (xpm = global_client_maps; xpm; xpm = xpm->xpm_next) {
// find an available unused comm area
// find an available unused comm area
for (i = 0; i < global_slots_per_map; i++)
{
if (xpm->xpm_ids[i] == XPM_FREE)
for (i = 0; i < global_slots_per_map; i++)
{
if (xpm->xpm_ids[i] == XPM_FREE)
break;
}
if (i < global_slots_per_map) {
xpm->xpm_count++;
xpm->xpm_ids[i] = XPM_BUSY;
j = xpm->xpm_number;
break;
}
j++;
}
if (i < global_slots_per_map) {
xpm->xpm_count++;
xpm->xpm_ids[i] = XPM_BUSY;
j = xpm->xpm_number;
break;
}
j++;
}
XNET_UNLOCK();
} // xnet_mutex scope
// if the mapped file structure has not yet been initialized,
// make one now