⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plserver.c

📁 了解服务器的内部结构
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *	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 "../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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -