mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
Remove PLSERVER (page lock server).
This commit is contained in:
parent
17a9c20884
commit
3e05f5b931
@ -199,16 +199,6 @@ int PIO_connection(TEXT * file_name, USHORT * file_length)
|
|||||||
**************************************/
|
**************************************/
|
||||||
int node;
|
int node;
|
||||||
|
|
||||||
#ifdef PLSERVER
|
|
||||||
|
|
||||||
/* Analyze the file name to see if a remote connection is required. If not,
|
|
||||||
quietly (sic) return. */
|
|
||||||
|
|
||||||
if (node = analyze(file_name, *file_length))
|
|
||||||
return PLS_connection(node);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
449
src/lock/pls.cpp
449
src/lock/pls.cpp
@ -1,449 +0,0 @@
|
|||||||
/*
|
|
||||||
* PROGRAM: JRD Lock Manager
|
|
||||||
* MODULE: pls.c
|
|
||||||
* DESCRIPTION: Page lock server interface
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Interbase Public
|
|
||||||
* License Version 1.0 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy
|
|
||||||
* of the License at http://www.Inprise.com/IPL.html
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an
|
|
||||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code was created by Inprise Corporation
|
|
||||||
* and its predecessors. Portions created by Inprise Corporation are
|
|
||||||
* Copyright (C) Inprise Corporation.
|
|
||||||
*
|
|
||||||
* All Rights Reserved.
|
|
||||||
* Contributor(s): ______________________________________.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "firebird.h"
|
|
||||||
#include "lock.h"
|
|
||||||
#include "plserver.h"
|
|
||||||
|
|
||||||
#include "/sys/ins/streams.ins.c"
|
|
||||||
#include "/sys/ins/ms.ins.c"
|
|
||||||
#include "/sys/ins/name.ins.c"
|
|
||||||
#include "/sys/ins/proc2.ins.c"
|
|
||||||
#include "/sys/ins/ipc.ins.c"
|
|
||||||
|
|
||||||
#define ALLOC pls_alloc
|
|
||||||
#define DATAGRAM_RETRY 10
|
|
||||||
|
|
||||||
/* Connection block for page/lock server */
|
|
||||||
|
|
||||||
typedef struct plc {
|
|
||||||
struct blk plc_header;
|
|
||||||
struct pld *plc_next; /* Next connection */
|
|
||||||
int plc_node; /* Node id of connection */
|
|
||||||
int plc_send_sequence; /* Next available packet sequence number */
|
|
||||||
int plc_recv_sequence; /* Sequence number of last packet received */
|
|
||||||
UCHAR plc_socket[20]; /* Apollo socket handle */
|
|
||||||
UCHAR plc_socket2[20]; /* Our socket handle */
|
|
||||||
int plc_connection_handle;
|
|
||||||
int plc_file_handle;
|
|
||||||
USHORT plc_length; /* Length of file name */
|
|
||||||
UCHAR plc_file[1]; /* Socket file name */
|
|
||||||
} *PLC;
|
|
||||||
|
|
||||||
static int connect(int, ipc_$socket_handle_t *);
|
|
||||||
static int error(UCHAR *, UCHAR *, status_$t);
|
|
||||||
static UCHAR *pls_alloc(USHORT);
|
|
||||||
static void pls_release(UCHAR *);
|
|
||||||
static void move(SCHAR *, SCHAR *, SSHORT);
|
|
||||||
|
|
||||||
static PLC connections;
|
|
||||||
|
|
||||||
#define NODE_MASK 0xFFFFF
|
|
||||||
|
|
||||||
|
|
||||||
/* Asknode Stuff */
|
|
||||||
|
|
||||||
std_$call void asknode_$info();
|
|
||||||
|
|
||||||
typedef SSHORT enum {
|
|
||||||
ask_who, who_r,
|
|
||||||
ask_time, time_r,
|
|
||||||
ask_node_root, node_root_r
|
|
||||||
} asknode_$kind_t;
|
|
||||||
|
|
||||||
#define asknode_$version 2
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
pinteger version;
|
|
||||||
asknode_$kind_t kind;
|
|
||||||
status_$t status;
|
|
||||||
uid_$t uid;
|
|
||||||
SCHAR stuff[256]; /* Random and various */
|
|
||||||
} asknode_$reply_t;
|
|
||||||
|
|
||||||
/* name_$ stuff */
|
|
||||||
|
|
||||||
std_$call void name_$gpath_dir();
|
|
||||||
|
|
||||||
SSHORT enum name_$namtyp_t {
|
|
||||||
name_$junk_flag,
|
|
||||||
name_$wdir_flag,
|
|
||||||
name_$ndir_flag,
|
|
||||||
name_$node_flag,
|
|
||||||
name_$root_flag,
|
|
||||||
name_$node_data_flag
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
PLC PLS_connection(int node, USHORT server_flag)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* P L S _ c o n n e c t i o n
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Establish a connection to a page/lock server on a given node.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
PHD header, reply;
|
|
||||||
UCHAR socket_name[32];
|
|
||||||
USHORT length;
|
|
||||||
uid_$t uid;
|
|
||||||
status_$t status;
|
|
||||||
ipc_$socket_handle_t handle, local_handle;
|
|
||||||
asknode_$reply_t node_info;
|
|
||||||
|
|
||||||
if (connect(node, &handle))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (connect(NULL, &local_handle))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* We seem to have a socket -- time to make a connection block */
|
|
||||||
|
|
||||||
connection = ALLOC(sizeof(struct plc) + length);
|
|
||||||
connection->plc_length = length;
|
|
||||||
connection->plc_node = node;
|
|
||||||
strcpy(connection->plc_file, socket_name);
|
|
||||||
move(&handle, connection->plc_socket, sizeof(handle));
|
|
||||||
move(&local_handle, connection->plc_socket2, sizeof(handle));
|
|
||||||
|
|
||||||
/* We at least have a socket handle. See if anybody is really there */
|
|
||||||
|
|
||||||
header.phd_type = PL_CONNECT;
|
|
||||||
proc2_$who_am_i(uid);
|
|
||||||
header.phd_misc = uid.low & NODE_MASK;
|
|
||||||
header.phd_flags = (server_flag) ? PHD_SERVER : 0;
|
|
||||||
status.all =
|
|
||||||
PLS_request(connection, &header, sizeof(header), &reply,
|
|
||||||
sizeof(reply), NULL, 0, 0);
|
|
||||||
|
|
||||||
if (status.all) {
|
|
||||||
PLS_disconnect(connection);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->plc_connection_handle = reply.phd_handle;
|
|
||||||
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
PLC PLS_find_connection(int node, USHORT server_flag)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* P L S _ f i n d _ c o n n e c t i o n
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Find a connection if it exists, otherwise create it.
|
|
||||||
* Note: This is used only by the page/lock server to
|
|
||||||
* avoid problems of dirty statics in Apollo installed images.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
|
|
||||||
/* See if connection exits */
|
|
||||||
|
|
||||||
for (connection = connections; connection;
|
|
||||||
connection = connection->plc_next) if (connection->plc_node == node)
|
|
||||||
return connection;
|
|
||||||
|
|
||||||
/* Connection doesn't exist -- try to make it */
|
|
||||||
|
|
||||||
if (!(connection = PLS_connection(node, server_flag)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
connection->plc_next = connections;
|
|
||||||
connections = connection;
|
|
||||||
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int PLS_request(
|
|
||||||
PLC connection,
|
|
||||||
PHD * header,
|
|
||||||
USHORT header_len,
|
|
||||||
PHD * reply,
|
|
||||||
USHORT reply_len,
|
|
||||||
UCHAR * data, USHORT send_len, USHORT receive_len)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* P L S _ r e q u e s t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Send a page/lock request and get response.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
USHORT send, wait, count, receive_length, header_length, next;
|
|
||||||
status_$t status;
|
|
||||||
ipc_$socket_handle_t handle;
|
|
||||||
|
|
||||||
/* Send the request until we get something back */
|
|
||||||
|
|
||||||
header->phd_connection = connection->plc_connection_handle;
|
|
||||||
BUMP_SEQUENCE(connection->plc_send_sequence);
|
|
||||||
header->phd_sequence = connection->plc_send_sequence;
|
|
||||||
send = TRUE;
|
|
||||||
wait = 10 * 4;
|
|
||||||
|
|
||||||
for (count = 0; count < DATAGRAM_RETRY; count++) {
|
|
||||||
if (send) {
|
|
||||||
header->phd_ack = connection->plc_recv_sequence;
|
|
||||||
ipc_$send(connection->plc_socket,
|
|
||||||
connection->plc_socket2,
|
|
||||||
*header, header_len, *data, send_len, status);
|
|
||||||
if (status.all)
|
|
||||||
return status.all;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait for and read reply */
|
|
||||||
|
|
||||||
ipc_$wait(connection->plc_socket2, wait, status);
|
|
||||||
if (status.all == ipc_$timeout)
|
|
||||||
continue;
|
|
||||||
if (status.all)
|
|
||||||
return status.all;
|
|
||||||
ipc_$rcv(connection->plc_socket2, header_len, /* out-hdr-buflen */
|
|
||||||
receive_len, /* out-data-buflen */
|
|
||||||
handle, *reply, /* out-hdr-buf */
|
|
||||||
reply_len, /* out-hdr-length */
|
|
||||||
*data, /* out-data-buf */
|
|
||||||
receive_length, /* out-data-length */
|
|
||||||
status); /* status */
|
|
||||||
if (status.all)
|
|
||||||
return status.all;
|
|
||||||
|
|
||||||
connection->plc_recv_sequence = reply->phd_sequence;
|
|
||||||
|
|
||||||
/* If the packet acknowleges something other than the one sent, re-transmit */
|
|
||||||
|
|
||||||
if (reply->phd_ack != connection->plc_send_sequence) {
|
|
||||||
send = TRUE;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If this is something other than an acknowlegement, be patient */
|
|
||||||
|
|
||||||
if (reply->phd_type != PL_ACK)
|
|
||||||
return FB_SUCCESS;
|
|
||||||
|
|
||||||
/* If we got an acknowlegement, the other guy has at least received the packet.
|
|
||||||
We should be more patient, but still probe looking for death */
|
|
||||||
|
|
||||||
wait = 30 * 4;
|
|
||||||
send = FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void PLS_disconnect( PLC connection)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* P L S _ d i s c o n n e c t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Break a remote connection.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
status_$t status;
|
|
||||||
|
|
||||||
ipc_$close(connection->plc_file, connection->plc_length, status);
|
|
||||||
if (status.all)
|
|
||||||
error_$print(&status);
|
|
||||||
|
|
||||||
ipc_$delete(connection->plc_file, connection->plc_length, status);
|
|
||||||
if (status.all)
|
|
||||||
error_$print(&status);
|
|
||||||
|
|
||||||
/* Close a client channel */
|
|
||||||
|
|
||||||
pls_release(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int connect( int node, ipc_$socket_handle_t * handle)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* c o n n e c t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Try to establish a physical connection to the page
|
|
||||||
* lock server on a given node.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PHD header, reply;
|
|
||||||
UCHAR socket_name[32], root_name[256], *p;
|
|
||||||
USHORT length;
|
|
||||||
status_$t status;
|
|
||||||
asknode_$reply_t node_info;
|
|
||||||
|
|
||||||
/* If no node id was given, create a connection for ourselves */
|
|
||||||
|
|
||||||
if (!node) {
|
|
||||||
strcpy(socket_name, "gds.pl_server_XXXXXX");
|
|
||||||
mktemp(socket_name);
|
|
||||||
length = strlen(socket_name);
|
|
||||||
ipc_$create(socket_name, length, status);
|
|
||||||
if (status.all)
|
|
||||||
return error("ipc_$create", socket_name, status);
|
|
||||||
ipc_$open(socket_name, length, 4, *handle, status);
|
|
||||||
if (status.all)
|
|
||||||
return error("ipc_$open", socket_name, status);
|
|
||||||
unlink(socket_name);
|
|
||||||
return FB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* File is open by another node. Sigh. Make up a nice filename */
|
|
||||||
|
|
||||||
asknode_$info(ask_node_root, node, 0, node_info, status);
|
|
||||||
if (status.all)
|
|
||||||
return error("asknode_$info", " ", status);
|
|
||||||
|
|
||||||
if (node_info.status.all)
|
|
||||||
return error("asknode_$info", "remote site", node_info.status);
|
|
||||||
|
|
||||||
name_$gpath_dir(node_info.uid, name_$root_flag, root_name, length,
|
|
||||||
status);
|
|
||||||
if (status.all)
|
|
||||||
return error("name_$gpath_dir", "", status);
|
|
||||||
|
|
||||||
root_name[length] = 0;
|
|
||||||
sprintf(socket_name, "%s/sys/gds.plserver_%x", root_name, node);
|
|
||||||
length = strlen(socket_name);
|
|
||||||
|
|
||||||
/* See if we can get a socket for the server. If not, don't bother
|
|
||||||
continuing this non-sense */
|
|
||||||
|
|
||||||
ipc_$resolve(socket_name, length, *handle, status);
|
|
||||||
if (status.all) {
|
|
||||||
for (p = socket_name + 2; *p && *p != '/'; p++)
|
|
||||||
if (*p >= 'A' && *p <= 'Z')
|
|
||||||
*p = *p - 'A' + 'a';
|
|
||||||
ipc_$resolve(socket_name, length, *handle, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.all)
|
|
||||||
return error("ipc_$resolve", socket_name, status);
|
|
||||||
|
|
||||||
return FB_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int error( UCHAR * operation, UCHAR * object, status_$t status)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* e r r o r
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* A system service error has occurred.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
ib_printf("Page/lock service error occurred during %s on \"%s\"\n",
|
|
||||||
operation, object);
|
|
||||||
error_$print(status);
|
|
||||||
|
|
||||||
return status.all;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static UCHAR *pls_alloc( USHORT size)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* p l s _ a l l o c
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Allocate a block.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
UCHAR *blk, *p, *end;
|
|
||||||
|
|
||||||
blk = p = gds__alloc(size);
|
|
||||||
end = p + size;
|
|
||||||
|
|
||||||
while (p < end)
|
|
||||||
*p++ = 0;
|
|
||||||
|
|
||||||
return blk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void pls_release( UCHAR * blk)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* p l s _ r e l e a s e
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Release a block.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
gds__free(blk);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void move(
|
|
||||||
SCHAR * from,
|
|
||||||
SCHAR * to, SSHORT length)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* m o v e
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Move a byte string as fast as possible.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
if (length)
|
|
||||||
do
|
|
||||||
*to++ = *from++;
|
|
||||||
while (--length);
|
|
||||||
}
|
|
@ -1,684 +0,0 @@
|
|||||||
/*
|
|
||||||
* PROGRAM: JRD Remote Interface/Server
|
|
||||||
* MODULE: plserver.c
|
|
||||||
* DESCRIPTION: Page/lock server
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Interbase Public
|
|
||||||
* License Version 1.0 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy
|
|
||||||
* of the License at http://www.Inprise.com/IPL.html
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an
|
|
||||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code was created by Inprise Corporation
|
|
||||||
* and its predecessors. Portions created by Inprise Corporation are
|
|
||||||
* Copyright (C) Inprise Corporation.
|
|
||||||
*
|
|
||||||
* All Rights Reserved.
|
|
||||||
* Contributor(s): ______________________________________.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "firebird.h"
|
|
||||||
#include "../jrd/ib_stdio.h"
|
|
||||||
|
|
||||||
#include "../jrd/common.h"
|
|
||||||
#include "plserver.h"
|
|
||||||
|
|
||||||
#include "/sys/ins/base.ins.c"
|
|
||||||
#include "/sys/ins/ipc.ins.c"
|
|
||||||
#include "/sys/ins/error.ins.c"
|
|
||||||
#include "/sys/ins/proc2.ins.c"
|
|
||||||
#include "/sys/ins/ms.ins.c"
|
|
||||||
|
|
||||||
/* Block used to manage connections */
|
|
||||||
|
|
||||||
typedef struct plc {
|
|
||||||
struct plc *plc_next;
|
|
||||||
int plc_send_sequence; /* Next available packet sequence number */
|
|
||||||
int plc_recv_sequence; /* Sequence number of last packet received */
|
|
||||||
UCHAR plc_socket[20]; /* Apollo socket handle */
|
|
||||||
struct fat *plc_attachments;
|
|
||||||
struct blk *plc_server; /* Server connection on client node */
|
|
||||||
} *PLC;
|
|
||||||
|
|
||||||
/* File attachment blocks */
|
|
||||||
|
|
||||||
typedef struct fat {
|
|
||||||
struct plc *fat_connection; /* Connection block for file */
|
|
||||||
struct file *fat_file; /* File block for attachment */
|
|
||||||
struct fat *fat_next_connection; /* Next FAT in connections list */
|
|
||||||
struct fat *fat_next_file; /* Next FAT in file list */
|
|
||||||
} *FAT;
|
|
||||||
|
|
||||||
/* File window and file blocks */
|
|
||||||
|
|
||||||
typedef struct fwin {
|
|
||||||
struct pag *fwin_address; /* Address of mapped region */
|
|
||||||
SLONG fwin_length; /* Length of mapped region */
|
|
||||||
SLONG fwin_offset; /* Offset in bytes of region */
|
|
||||||
SLONG fwin_activity; /* Accesses since window turn */
|
|
||||||
} FWIN;
|
|
||||||
|
|
||||||
#define WINDOWS 3
|
|
||||||
#define WINDOW_LENGTH 32768
|
|
||||||
|
|
||||||
typedef struct fil {
|
|
||||||
struct file *fil_next; /* Next file in server */
|
|
||||||
FAT fil_attachments; /* List of attachments to file */
|
|
||||||
USHORT fil_count; /* Number of window */
|
|
||||||
FWIN fil_windows[WINDOWS]; /* File windows */
|
|
||||||
USHORT fil_length; /* File name length */
|
|
||||||
UCHAR fil_name[1]; /* File name */
|
|
||||||
} *FIL;
|
|
||||||
|
|
||||||
static UCHAR *alloc(USHORT);
|
|
||||||
static int client_error(PLC, UCHAR *, status_$t);
|
|
||||||
static PLC connect(PHD *, UCHAR *);
|
|
||||||
static void detach(FAT);
|
|
||||||
static void disconnect(PHD *);
|
|
||||||
static void ipc_error(status_$t, UCHAR *);
|
|
||||||
static UCHAR *map_file(PLC, FIL, ULONG);
|
|
||||||
static void move(UCHAR *, UCHAR *, USHORT);
|
|
||||||
static void open(PHD *, UCHAR *);
|
|
||||||
static void page_read(PHD *);
|
|
||||||
static void page_write(PHD *, UCHAR *);
|
|
||||||
static void release(UCHAR *);
|
|
||||||
static void reply(PLC, PHD *, USHORT, UCHAR *, USHORT);
|
|
||||||
static int socket_eql(UCHAR *, UCHAR *);
|
|
||||||
|
|
||||||
static PLC connections, servers;
|
|
||||||
static FIL files;
|
|
||||||
static ipc_$socket_handle_t server_handle;
|
|
||||||
|
|
||||||
static PLC connect();
|
|
||||||
|
|
||||||
|
|
||||||
void main( int argc, char **argv)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* m a i n
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Apollo specific page/lock server. The page and lock functions
|
|
||||||
* are independent (sigh), but there is no reason to have multiple
|
|
||||||
* servers.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
UCHAR file[32], header_buffer[128], data_buffer[1024];
|
|
||||||
USHORT header_length, data_length;
|
|
||||||
PHD *header;
|
|
||||||
PLC connection;
|
|
||||||
status_$t status;
|
|
||||||
uid_$t process_uid;
|
|
||||||
ipc_$socket_handle_t client_handle;
|
|
||||||
|
|
||||||
/* Open the socket for activity */
|
|
||||||
|
|
||||||
proc2_$who_am_i(process_uid);
|
|
||||||
sprintf(file, "/sys/gds.plserver_%x", process_uid.low & 0xFFFFF);
|
|
||||||
data_length = strlen(file);
|
|
||||||
|
|
||||||
ipc_$create(file, data_length, status);
|
|
||||||
|
|
||||||
ipc_$open(file, data_length, 4, server_handle, status);
|
|
||||||
if (status.all)
|
|
||||||
ipc_error(status, "ipc_$open");
|
|
||||||
|
|
||||||
/* Process messages */
|
|
||||||
|
|
||||||
header = header_buffer;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
for (;;) {
|
|
||||||
ipc_$wait(server_handle, 4 * 10, status);
|
|
||||||
if (!status.all)
|
|
||||||
break;
|
|
||||||
if (status.all != ipc_$timeout)
|
|
||||||
ipc_error(status, "ipc_$wait");
|
|
||||||
for (connection = connections; connection;
|
|
||||||
connection = connection->plc_next) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ipc_$rcv(server_handle,
|
|
||||||
sizeof(header_buffer),
|
|
||||||
sizeof(data_buffer),
|
|
||||||
client_handle,
|
|
||||||
header_buffer,
|
|
||||||
header_length, data_buffer, data_length, status);
|
|
||||||
if (status.all)
|
|
||||||
ipc_error(status, "ipc_$rcv");
|
|
||||||
|
|
||||||
if (!(connection = header->phd_connection))
|
|
||||||
connection = connect(header, &client_handle);
|
|
||||||
|
|
||||||
/* Get rid of duplicate packet */
|
|
||||||
|
|
||||||
if (header->phd_sequence == connection->plc_recv_sequence)
|
|
||||||
continue;
|
|
||||||
connection->plc_recv_sequence = header->phd_sequence;
|
|
||||||
|
|
||||||
switch (header->phd_type) {
|
|
||||||
case PL_CONNECT:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PL_DISCONNECT:
|
|
||||||
disconnect(header);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PL_PAGE_OPEN:
|
|
||||||
open(header, data_buffer);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PL_PAGE_READ:
|
|
||||||
page_read(header);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PL_PAGE_WRITE:
|
|
||||||
page_write(header, data_buffer);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ib_fprintf(ib_stderr, "packet type %d not understood\n",
|
|
||||||
header->phd_type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static UCHAR *alloc( USHORT size)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* a l l o c
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Allocate a zero filled block.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
UCHAR *blk, *p, *end;
|
|
||||||
|
|
||||||
blk = p = gds__alloc(size);
|
|
||||||
do
|
|
||||||
*p++ = 0;
|
|
||||||
while (--size);
|
|
||||||
|
|
||||||
return blk;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int client_error( PLC connection, UCHAR * string, status_$t status)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* c l i e n t _ e r r o r
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Report an error to the client.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PHD packet;
|
|
||||||
|
|
||||||
packet.phd_type = PL_ERROR;
|
|
||||||
packet.phd_length = 0;
|
|
||||||
packet.phd_misc = status.all;
|
|
||||||
strcpy(packet.phd_string, string);
|
|
||||||
reply(connection, &packet, sizeof(packet), NULL, 0);
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static PLC connect( PHD * header, UCHAR * socket)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* c o n n e c t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Accept incoming connection.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
|
|
||||||
/* Check for connection already active */
|
|
||||||
|
|
||||||
for (connection = connections; connection;
|
|
||||||
connection =
|
|
||||||
connection->plc_next) if (socket_eql(connection->plc_socket, socket))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!connection) {
|
|
||||||
connection = alloc(sizeof(struct plc));
|
|
||||||
connection->plc_next = connections;
|
|
||||||
connections = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
header->phd_handle = connection;
|
|
||||||
connection->plc_recv_sequence = header->phd_sequence;
|
|
||||||
move(socket, connection->plc_socket, sizeof(connection->plc_socket));
|
|
||||||
reply(connection, header, sizeof(struct phd), NULL, 0);
|
|
||||||
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void detach( FAT attachment)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* d e t a c h
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Detach from a file segment.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
FIL file, *file_ptr;
|
|
||||||
FAT *fat;
|
|
||||||
FWIN *win, *end;
|
|
||||||
status_$t status;
|
|
||||||
|
|
||||||
connection = attachment->fat_connection;
|
|
||||||
file = attachment->fat_file;
|
|
||||||
|
|
||||||
/* Disconnect attachment from connection. */
|
|
||||||
|
|
||||||
for (fat = &connection->plc_attachments; *fat;
|
|
||||||
fat = &(*fat)->fat_next_connection) if (*fat == attachment) {
|
|
||||||
*fat = attachment->fat_next_connection;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disconnect attachment from file. If file loses its last attachment,
|
|
||||||
release the file */
|
|
||||||
|
|
||||||
for (fat = &file->fil_attachments; *fat; fat = &(*fat)->fat_next_file)
|
|
||||||
if (*fat == attachment) {
|
|
||||||
*fat = attachment->fat_next_file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!file->fil_attachments) {
|
|
||||||
for (win = file->fil_windows, end = win + file->fil_count; win < end;
|
|
||||||
win++)
|
|
||||||
ms_$unmap(win->fwin_address, win->fwin_length, status);
|
|
||||||
for (file_ptr = &files; *file_ptr; file_ptr = &(*file_ptr)->fil_next)
|
|
||||||
if (*file_ptr = file) {
|
|
||||||
*file_ptr = file->fil_next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
release(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
release(attachment);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void disconnect( PHD * packet)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* d i s c o n n e c t
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Break a connection.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection, *ptr;
|
|
||||||
|
|
||||||
connection = packet->phd_connection;
|
|
||||||
packet->phd_type = PL_REPLY;
|
|
||||||
reply(connection, packet, sizeof(struct phd), NULL, 0);
|
|
||||||
|
|
||||||
/* Get rid of file segments */
|
|
||||||
|
|
||||||
while (connection->plc_attachments)
|
|
||||||
detach(connection->plc_attachments);
|
|
||||||
|
|
||||||
/* Get rid of connection block */
|
|
||||||
|
|
||||||
for (ptr = &connections; *ptr; ptr = &(*ptr)->plc_next)
|
|
||||||
if (*ptr == connection) {
|
|
||||||
*ptr = connection->plc_next;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ipc_error( status_$t status, UCHAR * string)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* i p c _ e r r o r
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* A more or less fatal error occurred. Seppicu time.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
ib_fprintf(ib_stderr, "Error during %s operation\n", string);
|
|
||||||
error_$print(status);
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static UCHAR *map_file( PLC connection, FIL file, ULONG offset)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* m a p _ f i l e
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Map a page in a file.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
FWIN *window, *win, *end;
|
|
||||||
SLONG section;
|
|
||||||
status_$t status;
|
|
||||||
USHORT i, length;
|
|
||||||
UCHAR *address;
|
|
||||||
|
|
||||||
win = NULL;
|
|
||||||
|
|
||||||
/* Search for a window that is already mapped. */
|
|
||||||
|
|
||||||
for (window = file->fil_windows, end = window + file->fil_count;
|
|
||||||
window < end; window++) {
|
|
||||||
if (offset >= window->fwin_offset &&
|
|
||||||
offset < window->fwin_offset + window->fwin_length) goto exit;
|
|
||||||
if (!win || window->fwin_activity < win->fwin_activity)
|
|
||||||
win = window;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If not all windows have been used, use another */
|
|
||||||
|
|
||||||
section = offset & ~(WINDOW_LENGTH - 1);
|
|
||||||
|
|
||||||
if (file->fil_count < WINDOWS) {
|
|
||||||
address = ms_$mapl(file->fil_name, file->fil_length, section,
|
|
||||||
(SLONG) WINDOW_LENGTH, ms_$cowriters, ms_$wr,
|
|
||||||
(SSHORT) - 1, window->fwin_length, status);
|
|
||||||
|
|
||||||
if (status.all)
|
|
||||||
return client_error(connection, "ms_$mapl", status);
|
|
||||||
++file->fil_count;
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Window not found, remap it. */
|
|
||||||
|
|
||||||
window = win;
|
|
||||||
address = ms_$remap(window->fwin_address, section,
|
|
||||||
(SLONG) WINDOW_LENGTH, window->fwin_length, status);
|
|
||||||
|
|
||||||
if (status.all)
|
|
||||||
return client_error(connection, "ms_$remap", status);
|
|
||||||
|
|
||||||
/* Down grade activity after window shift */
|
|
||||||
|
|
||||||
for (win = file->fil_windows; win < end; win++)
|
|
||||||
win->fwin_activity >>= 2;
|
|
||||||
|
|
||||||
finish:
|
|
||||||
|
|
||||||
window->fwin_address = address;
|
|
||||||
window->fwin_offset = section;
|
|
||||||
window->fwin_activity = 0;
|
|
||||||
|
|
||||||
exit:
|
|
||||||
|
|
||||||
++window->fwin_activity;
|
|
||||||
return (SCHAR *) window->fwin_address + offset - window->fwin_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void move( UCHAR * from, UCHAR * to, USHORT length)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* m o v e
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Move a fixed length string.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
if (length)
|
|
||||||
do
|
|
||||||
*to++ = *from++;
|
|
||||||
while (--length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void open( PHD * packet, UCHAR * data)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* o p e n
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Open a file.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
FIL file;
|
|
||||||
FAT attachment;
|
|
||||||
FWIN *window;
|
|
||||||
status_$t status;
|
|
||||||
|
|
||||||
data[packet->phd_length] = 0;
|
|
||||||
connection = packet->phd_connection;
|
|
||||||
|
|
||||||
/* Check to see if file is already known */
|
|
||||||
|
|
||||||
for (file = files; file; file = file->fil_next)
|
|
||||||
if (!strcmp(data, file->fil_name))
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* If file doesn't exist, create it now */
|
|
||||||
|
|
||||||
if (!file) {
|
|
||||||
file = alloc(sizeof(struct fil) + packet->phd_length);
|
|
||||||
file->fil_length = packet->phd_length;
|
|
||||||
strcpy(file->fil_name, data);
|
|
||||||
file->fil_next = files;
|
|
||||||
files = file;
|
|
||||||
file->fil_count = 1;
|
|
||||||
|
|
||||||
/* Map the file as appropriate */
|
|
||||||
|
|
||||||
window = file->fil_windows;
|
|
||||||
window->fwin_address = ms_$mapl(file->fil_name, file->fil_length,
|
|
||||||
window->fwin_offset,
|
|
||||||
(SLONG) WINDOW_LENGTH, ms_$cowriters,
|
|
||||||
ms_$wr, (SSHORT) - 1,
|
|
||||||
window->fwin_length, status);
|
|
||||||
if (status.all)
|
|
||||||
client_error(connection, "ms_$mapl", status);
|
|
||||||
file->fil_count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect file and connection block */
|
|
||||||
|
|
||||||
attachment = alloc(sizeof(struct fat));
|
|
||||||
attachment->fat_connection = connection;
|
|
||||||
attachment->fat_file = file;
|
|
||||||
attachment->fat_next_file = file->fil_attachments;
|
|
||||||
file->fil_attachments = attachment;
|
|
||||||
attachment->fat_next_connection = connection->plc_attachments;
|
|
||||||
connection->plc_attachments = attachment;
|
|
||||||
|
|
||||||
/* Send a reply */
|
|
||||||
|
|
||||||
packet->phd_handle = attachment;
|
|
||||||
packet->phd_type = PL_REPLY;
|
|
||||||
reply(connection, packet, sizeof(struct phd), NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void page_read( PHD * packet)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* p a g e _ r e a d
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Read a database page.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
FIL file;
|
|
||||||
FAT attachment;
|
|
||||||
UCHAR *ptr;
|
|
||||||
status_$t status;
|
|
||||||
|
|
||||||
connection = packet->phd_connection;
|
|
||||||
attachment = packet->phd_handle;
|
|
||||||
file = attachment->fat_file;
|
|
||||||
|
|
||||||
/* Map appropriate part of file */
|
|
||||||
|
|
||||||
ptr = map_file(connection, file, packet->phd_misc);
|
|
||||||
if (ptr == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Send a reply */
|
|
||||||
|
|
||||||
packet->phd_handle = attachment;
|
|
||||||
packet->phd_type = PL_REPLY;
|
|
||||||
reply(connection, packet, sizeof(struct phd), ptr, packet->phd_length);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void page_write( PHD * packet, UCHAR * data)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* p a g e _ w r i t e
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Write a database page.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
PLC connection;
|
|
||||||
FIL file;
|
|
||||||
FAT attachment;
|
|
||||||
UCHAR *ptr;
|
|
||||||
status_$t status;
|
|
||||||
|
|
||||||
attachment = packet->phd_handle;
|
|
||||||
connection = packet->phd_connection;
|
|
||||||
file = attachment->fat_file;
|
|
||||||
|
|
||||||
/* Map appropriate part of file */
|
|
||||||
|
|
||||||
ptr = map_file(connection, file, packet->phd_misc);
|
|
||||||
if (ptr == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
move(data, ptr, packet->phd_length);
|
|
||||||
|
|
||||||
/* Send a reply */
|
|
||||||
|
|
||||||
packet->phd_handle = attachment;
|
|
||||||
packet->phd_type = PL_REPLY;
|
|
||||||
reply(connection, packet, sizeof(struct phd), NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void release( UCHAR * blk)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* r e l e a s e
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Release a block.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
gds__free(blk);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void reply(
|
|
||||||
PLC connection,
|
|
||||||
PHD * header,
|
|
||||||
USHORT header_len, UCHAR * data, USHORT data_len)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* r e p l y
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Reply to a request.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
status_$t status;
|
|
||||||
|
|
||||||
BUMP_SEQUENCE(connection->plc_send_sequence);
|
|
||||||
header->phd_sequence = connection->plc_send_sequence;
|
|
||||||
header->phd_ack = connection->plc_recv_sequence;
|
|
||||||
|
|
||||||
ipc_$send(connection->plc_socket, server_handle,
|
|
||||||
*header, header_len, *data, data_len, status);
|
|
||||||
if (status.all)
|
|
||||||
ipc_error(status, "icp_$send");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int socket_eql( UCHAR * socket1, UCHAR * socket2)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* s o c k e t _ e q l
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Compare two sockets for equality.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
UCHAR *end;
|
|
||||||
|
|
||||||
end = socket1 + sizeof(struct ipc_$socket_handle);
|
|
||||||
|
|
||||||
while (socket1 < end)
|
|
||||||
if (*socket1++ != socket2++)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
/*
|
|
||||||
* PROGRAM: JRD Remote Interface/Server
|
|
||||||
* MODULE: plserver.h
|
|
||||||
* DESCRIPTION: Page/lock server
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Interbase Public
|
|
||||||
* License Version 1.0 (the "License"); you may not use this file
|
|
||||||
* except in compliance with the License. You may obtain a copy
|
|
||||||
* of the License at http://www.Inprise.com/IPL.html
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an
|
|
||||||
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
|
|
||||||
* or implied. See the License for the specific language governing
|
|
||||||
* rights and limitations under the License.
|
|
||||||
*
|
|
||||||
* The Original Code was created by Inprise Corporation
|
|
||||||
* and its predecessors. Portions created by Inprise Corporation are
|
|
||||||
* Copyright (C) Inprise Corporation.
|
|
||||||
*
|
|
||||||
* All Rights Reserved.
|
|
||||||
* Contributor(s): ______________________________________.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _ISC_LOCK_PLSERVER_H_
|
|
||||||
#define _ISC_LOCK_PLSERVER_H_
|
|
||||||
|
|
||||||
/* General usage packet types */
|
|
||||||
|
|
||||||
#define PL_CONNECT 1 /* Establish connection */
|
|
||||||
#define PL_DISCONNECT 2 /* Break connection */
|
|
||||||
#define PL_ACK 3 /* Acknowledge message */
|
|
||||||
#define PL_ERROR 4 /* An error occurred */
|
|
||||||
#define PL_REPLY 5 /* Generic reply */
|
|
||||||
|
|
||||||
/* Packet types for page operations */
|
|
||||||
|
|
||||||
#define PL_PAGE_OPEN 10 /* Open existing file */
|
|
||||||
#define PL_PAGE_CREATE 11 /* Create new file */
|
|
||||||
#define PL_PAGE_READ 12 /* Read file data */
|
|
||||||
#define PL_PAGE_WRITE 13 /* Write file data */
|
|
||||||
|
|
||||||
/* Packet types for lock operations */
|
|
||||||
|
|
||||||
#define PL_LOCK_ENQ 20 /* Enqueue on lock */
|
|
||||||
#define PL_LOCK_CVT 21 /* Convert existing lock */
|
|
||||||
#define PL_LOCK_DEQ 22 /* Dequeue lock */
|
|
||||||
#define PL_LOCK_GRANT 23 /* Grant lock */
|
|
||||||
#define PL_LOCK_DENY 24 /* Deny lock */
|
|
||||||
#define PL_LOCK_BLOCK 25 /* Existing lock is blocking another process */
|
|
||||||
|
|
||||||
/* Generate packet format */
|
|
||||||
|
|
||||||
typedef struct phd {
|
|
||||||
UCHAR phd_type; /* Packet type */
|
|
||||||
UCHAR phd_flags; /* Misc flags */
|
|
||||||
USHORT phd_sequence; /* Packet sequence number */
|
|
||||||
USHORT phd_ack; /* Acknowleding packet */
|
|
||||||
int *phd_connection; /* Connection handle */
|
|
||||||
int *phd_handle; /* Internal handle */
|
|
||||||
USHORT phd_length; /* Miscellaneous usage */
|
|
||||||
int phd_misc; /* Also miscellaneous usage */
|
|
||||||
UCHAR phd_string[16]; /* Associated string */
|
|
||||||
} PHD;
|
|
||||||
|
|
||||||
#define PHD_SERVER 1 /* Connection is from a server */
|
|
||||||
|
|
||||||
#define BUMP_SEQUENCE(n) n = (++n == 10000) ? 1 : n;
|
|
||||||
|
|
||||||
#endif /* _ISC_LOCK_PLSERVER_H_ */
|
|
Loading…
Reference in New Issue
Block a user