Native shared memory implementation for win32.
Uses same underlying tech as before, but not the sysv emulation layer.
This commit is contained in:
parent
3b765dba78
commit
18d82d03b5
10
configure
vendored
10
configure
vendored
@ -22278,13 +22278,21 @@ fi
|
||||
|
||||
|
||||
# Select shared-memory implementation type.
|
||||
if test "$PORTNAME" != "win32"; then
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_SYSV_SHARED_MEMORY 1
|
||||
_ACEOF
|
||||
|
||||
SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
|
||||
SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
|
||||
else
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_WIN32_SHARED_MEMORY 1
|
||||
_ACEOF
|
||||
|
||||
SHMEM_IMPLEMENTATION="src/backend/port/win32_shmem.c"
|
||||
fi
|
||||
|
||||
# If not set in template file, set bytes to use libc memset()
|
||||
if test x"$MEMSET_LOOP_LIMIT" = x"" ; then
|
||||
|
12
configure.in
12
configure.in
@ -1,5 +1,5 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl $PostgreSQL: pgsql/configure.in,v 1.502 2007/02/21 15:12:39 momjian Exp $
|
||||
dnl $PostgreSQL: pgsql/configure.in,v 1.503 2007/03/21 14:39:23 mha Exp $
|
||||
dnl
|
||||
dnl Developers, please strive to achieve this order:
|
||||
dnl
|
||||
@ -1367,9 +1367,13 @@ fi
|
||||
|
||||
|
||||
# Select shared-memory implementation type.
|
||||
AC_DEFINE(USE_SYSV_SHARED_MEMORY, 1, [Define to select SysV-style shared memory.])
|
||||
SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
|
||||
|
||||
if test "$PORTNAME" != "win32"; then
|
||||
AC_DEFINE(USE_SYSV_SHARED_MEMORY, 1, [Define to select SysV-style shared memory.])
|
||||
SHMEM_IMPLEMENTATION="src/backend/port/sysv_shmem.c"
|
||||
else
|
||||
AC_DEFINE(USE_WIN32_SHARED_MEMORY, 1, [Define to select Win32-style shared memory.])
|
||||
SHMEM_IMPLEMENTATION="src/backend/port/win32_shmem.c"
|
||||
fi
|
||||
|
||||
# If not set in template file, set bytes to use libc memset()
|
||||
if test x"$MEMSET_LOOP_LIMIT" = x"" ; then
|
||||
|
@ -10,7 +10,7 @@
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/port/sysv_shmem.c,v 1.49 2007/02/06 16:20:23 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/port/sysv_shmem.c,v 1.50 2007/03/21 14:39:23 mha Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -195,11 +195,8 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
|
||||
{
|
||||
IpcMemoryId shmId = (IpcMemoryId) id2;
|
||||
struct shmid_ds shmStat;
|
||||
|
||||
#ifndef WIN32
|
||||
struct stat statbuf;
|
||||
PGShmemHeader *hdr;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We detect whether a shared memory segment is in use by seeing whether
|
||||
@ -238,11 +235,8 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
|
||||
/*
|
||||
* Try to attach to the segment and see if it matches our data directory.
|
||||
* This avoids shmid-conflict problems on machines that are running
|
||||
* several postmasters under the same userid. On Windows, which doesn't
|
||||
* have useful inode numbers, we can't do this so we punt and assume there
|
||||
* is a conflict.
|
||||
* several postmasters under the same userid.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
if (stat(DataDir, &statbuf) < 0)
|
||||
return true; /* if can't stat, be conservative */
|
||||
|
||||
@ -265,7 +259,6 @@ PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
|
||||
|
||||
/* Trouble --- looks a lot like there's still live backends */
|
||||
shmdt((void *) hdr);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -296,10 +289,7 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
|
||||
void *memAddress;
|
||||
PGShmemHeader *hdr;
|
||||
IpcMemoryId shmid;
|
||||
|
||||
#ifndef WIN32
|
||||
struct stat statbuf;
|
||||
#endif
|
||||
|
||||
/* Room for a header? */
|
||||
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
|
||||
@ -372,7 +362,6 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
|
||||
hdr->creatorPID = getpid();
|
||||
hdr->magic = PGShmemMagic;
|
||||
|
||||
#ifndef WIN32
|
||||
/* Fill in the data directory ID info, too */
|
||||
if (stat(DataDir, &statbuf) < 0)
|
||||
ereport(FATAL,
|
||||
@ -381,7 +370,6 @@ PGSharedMemoryCreate(Size size, bool makePrivate, int port)
|
||||
DataDir)));
|
||||
hdr->device = statbuf.st_dev;
|
||||
hdr->inode = statbuf.st_ino;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize space allocation status for segment.
|
||||
|
@ -4,7 +4,7 @@
|
||||
# Makefile for backend/port/win32
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $PostgreSQL: pgsql/src/backend/port/win32/Makefile,v 1.9 2007/01/20 17:16:12 petere Exp $
|
||||
# $PostgreSQL: pgsql/src/backend/port/win32/Makefile,v 1.10 2007/03/21 14:39:23 mha Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@ -12,7 +12,7 @@ subdir = src/backend/port/win32
|
||||
top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global
|
||||
|
||||
OBJS = shmem.o timer.o socket.o signal.o security.o
|
||||
OBJS = timer.o socket.o signal.o security.o
|
||||
|
||||
all: SUBSYS.o
|
||||
|
||||
|
@ -1,128 +0,0 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* shmem.c
|
||||
* Microsoft Windows Win32 Shared Memory Emulation
|
||||
*
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32/shmem.c,v 1.14 2007/01/05 22:19:35 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "postgres.h"
|
||||
|
||||
static DWORD s_segsize = 0;
|
||||
|
||||
/* Detach from a shared mem area based on its address */
|
||||
int
|
||||
shmdt(const void *shmaddr)
|
||||
{
|
||||
if (UnmapViewOfFile((LPCVOID *) shmaddr))
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Attach to an existing area */
|
||||
void *
|
||||
shmat(int memId, void *shmaddr, int flag)
|
||||
{
|
||||
/* TODO -- shmat needs to count # attached to shared mem */
|
||||
void *lpmem = MapViewOfFileEx((HANDLE) memId,
|
||||
FILE_MAP_WRITE | FILE_MAP_READ,
|
||||
0, 0, /* (DWORD)pshmdsc->segsize */ 0 /* s_segsize */ , shmaddr);
|
||||
|
||||
if (lpmem == NULL)
|
||||
{
|
||||
lpmem = (void *) -1;
|
||||
_dosmaperr(GetLastError());
|
||||
}
|
||||
|
||||
return lpmem;
|
||||
}
|
||||
|
||||
/* Control a shared mem area */
|
||||
int
|
||||
shmctl(int shmid, int flag, struct shmid_ds * dummy)
|
||||
{
|
||||
if (flag == IPC_RMID)
|
||||
{
|
||||
/* Delete the area */
|
||||
CloseHandle((HANDLE) shmid);
|
||||
return 0;
|
||||
}
|
||||
if (flag == IPC_STAT)
|
||||
{
|
||||
/* Can only test for if exists */
|
||||
int hmap = shmget(shmid, 0, 0);
|
||||
|
||||
if (hmap < 0)
|
||||
{
|
||||
/* Shared memory does not exist */
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Shared memory does exist and must be in use */
|
||||
shmctl(hmap, IPC_RMID, NULL); /* Release our hold on it */
|
||||
errno = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Get an area based on the IPC key */
|
||||
int
|
||||
shmget(int memKey, int size, int flag)
|
||||
{
|
||||
HANDLE hmap;
|
||||
char szShareMem[32];
|
||||
DWORD dwRet;
|
||||
|
||||
s_segsize = size;
|
||||
sprintf(szShareMem, "PostgreSQL.%d", memKey);
|
||||
|
||||
if (flag & IPC_CREAT)
|
||||
{
|
||||
hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, /* Use the swap file */
|
||||
NULL,
|
||||
PAGE_READWRITE, /* Memory is Read/Write */
|
||||
0L, /* Size Upper 32 Bits */
|
||||
(DWORD) s_segsize, /* Size Lower 32 bits */
|
||||
szShareMem);
|
||||
}
|
||||
else
|
||||
{
|
||||
hmap = OpenFileMapping(FILE_MAP_ALL_ACCESS,
|
||||
FALSE,
|
||||
szShareMem);
|
||||
if (!hmap)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
dwRet = GetLastError();
|
||||
if (dwRet == ERROR_ALREADY_EXISTS && hmap && (flag & (IPC_CREAT | IPC_EXCL)))
|
||||
{
|
||||
/* Caller wanted to create the segment -- error if already exists */
|
||||
CloseHandle(hmap);
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
else if (!hmap)
|
||||
{
|
||||
/* Unable to get shared memory */
|
||||
_dosmaperr(GetLastError());
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int) hmap;
|
||||
}
|
287
src/backend/port/win32_shmem.c
Normal file
287
src/backend/port/win32_shmem.c
Normal file
@ -0,0 +1,287 @@
|
||||
/*-------------------------------------------------------------------------
|
||||
*
|
||||
* win32_shmem.c
|
||||
* Implement shared memory using win32 facilities
|
||||
*
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/port/win32_shmem.c,v 1.1 2007/03/21 14:39:23 mha Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
#include "postgres.h"
|
||||
|
||||
#include "miscadmin.h"
|
||||
#include "storage/ipc.h"
|
||||
#include "storage/pg_shmem.h"
|
||||
|
||||
unsigned long UsedShmemSegID = 0;
|
||||
void *UsedShmemSegAddr = NULL;
|
||||
|
||||
static void pgwin32_SharedMemoryDelete(int status, Datum shmId);
|
||||
|
||||
/*
|
||||
* Generate shared memory segment name. Expand the data directory, to generate
|
||||
* an identifier unique for this data directory. Then replace all backslashes
|
||||
* with forward slashes, since backslashes aren't permitted in global object names.
|
||||
*
|
||||
* Store the shared memory segment in the Global\ namespace (requires NT2 TSE or
|
||||
* 2000, but that's all we support for other reasons as well), to make sure you can't
|
||||
* open two postmasters in different sessions against the same data directory.
|
||||
*
|
||||
* XXX: What happens with junctions? It's only someone breaking things on purpose,
|
||||
* and this is still better than before, but we might want to do something about
|
||||
* that sometime in the future.
|
||||
*/
|
||||
static char *
|
||||
GetSharedMemName(void)
|
||||
{
|
||||
char *retptr;
|
||||
DWORD bufsize;
|
||||
DWORD r;
|
||||
char *cp;
|
||||
|
||||
bufsize = GetFullPathName(DataDir, 0, NULL, NULL);
|
||||
if (bufsize == 0)
|
||||
elog(FATAL, "could not get size for full pathname of datadir %s: %lu",
|
||||
DataDir, GetLastError());
|
||||
|
||||
retptr = malloc(bufsize + 1 + 18); /* 1 NULL and 18 for
|
||||
* Global\PostgreSQL: */
|
||||
if (retptr == NULL)
|
||||
elog(FATAL, "could not allocate memory for shared memory name");
|
||||
|
||||
strcpy(retptr, "Global\\PostgreSQL:");
|
||||
r = GetFullPathName(DataDir, bufsize, retptr + 11, NULL);
|
||||
if (r == 0 || r > bufsize)
|
||||
elog(FATAL, "could not generate full pathname for datadir %s: %lu",
|
||||
DataDir, GetLastError());
|
||||
|
||||
for (cp = retptr; *cp; cp++)
|
||||
if (*cp == '\\')
|
||||
*cp = '/';
|
||||
|
||||
return retptr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PGSharedMemoryIsInUse
|
||||
*
|
||||
* Is a previously-existing shmem segment still existing and in use?
|
||||
*
|
||||
* The point of this exercise is to detect the case where a prior postmaster
|
||||
* crashed, but it left child backends that are still running. Therefore
|
||||
* we only care about shmem segments that are associated with the intended
|
||||
* DataDir. This is an important consideration since accidental matches of
|
||||
* shmem segment IDs are reasonably common.
|
||||
*
|
||||
*/
|
||||
bool
|
||||
PGSharedMemoryIsInUse(unsigned long id1, unsigned long id2)
|
||||
{
|
||||
char *szShareMem;
|
||||
HANDLE hmap;
|
||||
|
||||
szShareMem = GetSharedMemName();
|
||||
|
||||
hmap = OpenFileMapping(FILE_MAP_READ, FALSE, szShareMem);
|
||||
|
||||
free(szShareMem);
|
||||
|
||||
if (hmap == NULL)
|
||||
return false;
|
||||
|
||||
CloseHandle(hmap);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* PGSharedMemoryCreate
|
||||
*
|
||||
* Create a shared memory segment of the given size and initialize its
|
||||
* standard header.
|
||||
*
|
||||
* makePrivate means to always create a new segment, rather than attach to
|
||||
* or recycle any existing segment. On win32, we always create a new segment,
|
||||
* since there is no need for recycling (segments go away automatically
|
||||
* when the last backend exits)
|
||||
*
|
||||
*/
|
||||
PGShmemHeader *
|
||||
PGSharedMemoryCreate(Size size, bool makePrivate, int port)
|
||||
{
|
||||
void *memAddress;
|
||||
PGShmemHeader *hdr;
|
||||
HANDLE hmap,
|
||||
hmap2;
|
||||
char *szShareMem;
|
||||
|
||||
/* Room for a header? */
|
||||
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
|
||||
|
||||
szShareMem = GetSharedMemName();
|
||||
|
||||
UsedShmemSegAddr = NULL;
|
||||
|
||||
hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, /* Use the pagefile */
|
||||
NULL, /* Default security attrs */
|
||||
PAGE_READWRITE, /* Memory is Read/Write */
|
||||
0L, /* Size Upper 32 Bits */
|
||||
(DWORD) size, /* Size Lower 32 bits */
|
||||
szShareMem);
|
||||
|
||||
if (!hmap)
|
||||
ereport(FATAL,
|
||||
(errmsg("could not create shared memory segment: %lu", GetLastError()),
|
||||
errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s)", size, szShareMem)));
|
||||
|
||||
/*
|
||||
* If the segment already existed, CreateFileMapping() will return a
|
||||
* handle to the existing one.
|
||||
*/
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
/*
|
||||
* When recycling a shared memory segment, it may take a short while
|
||||
* before it gets dropped from the global namespace. So re-try after
|
||||
* sleeping for a second.
|
||||
*/
|
||||
CloseHandle(hmap); /* Close the old handle, since we got a valid
|
||||
* one to the previous segment. */
|
||||
|
||||
Sleep(1000);
|
||||
|
||||
hmap = CreateFileMapping((HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0L, (DWORD) size, szShareMem);
|
||||
if (!hmap)
|
||||
ereport(FATAL,
|
||||
(errmsg("could not create shared memory segment: %lu", GetLastError()),
|
||||
errdetail("Failed system call was CreateFileMapping(size=%lu, name=%s)", size, szShareMem)));
|
||||
|
||||
if (GetLastError() == ERROR_ALREADY_EXISTS)
|
||||
ereport(FATAL,
|
||||
(errmsg("pre-existing shared memory block is still in use"),
|
||||
errhint("Check if there are any old server processes still running, and terminate them.")));
|
||||
}
|
||||
|
||||
free(szShareMem);
|
||||
|
||||
/*
|
||||
* Make the handle inheritable
|
||||
*/
|
||||
if (!DuplicateHandle(GetCurrentProcess(), hmap, GetCurrentProcess(), &hmap2, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
ereport(FATAL,
|
||||
(errmsg("could not create shared memory segment: %lu", GetLastError()),
|
||||
errdetail("Failed system call was DuplicateHandle")));
|
||||
|
||||
/*
|
||||
* Close the old, non-inheritable handle. If this fails we don't really
|
||||
* care.
|
||||
*/
|
||||
if (!CloseHandle(hmap))
|
||||
elog(LOG, "could not close handle to shared memory: %lu", GetLastError());
|
||||
|
||||
|
||||
/* Register on-exit routine to delete the new segment */
|
||||
on_shmem_exit(pgwin32_SharedMemoryDelete, Int32GetDatum((unsigned long) hmap2));
|
||||
|
||||
/*
|
||||
* Get a pointer to the new shared memory segment. Map the whole segment
|
||||
* at once, and let the system decide on the initial address.
|
||||
*/
|
||||
memAddress = MapViewOfFileEx(hmap2, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, 0, NULL);
|
||||
if (!memAddress)
|
||||
ereport(FATAL,
|
||||
(errmsg("could not create shared memory segment: %lu", GetLastError()),
|
||||
errdetail("Failed system call was MapViewOfFileEx")));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* OK, we created a new segment. Mark it as created by this process. The
|
||||
* order of assignments here is critical so that another Postgres process
|
||||
* can't see the header as valid but belonging to an invalid PID!
|
||||
*/
|
||||
hdr = (PGShmemHeader *) memAddress;
|
||||
hdr->creatorPID = getpid();
|
||||
hdr->magic = PGShmemMagic;
|
||||
|
||||
/*
|
||||
* Initialize space allocation status for segment.
|
||||
*/
|
||||
hdr->totalsize = size;
|
||||
hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
|
||||
|
||||
/* Save info for possible future use */
|
||||
UsedShmemSegAddr = memAddress;
|
||||
UsedShmemSegID = (unsigned long) hmap2;
|
||||
|
||||
return hdr;
|
||||
}
|
||||
|
||||
/*
|
||||
* PGSharedMemoryReAttach
|
||||
*
|
||||
* Re-attach to an already existing shared memory segment. Use the
|
||||
* handle inherited from the postmaster.
|
||||
*
|
||||
* UsedShmemSegID and UsedShmemSegAddr are implicit parameters to this
|
||||
* routine. The caller must have already restored them to the postmaster's
|
||||
* values.
|
||||
*/
|
||||
void
|
||||
PGSharedMemoryReAttach(void)
|
||||
{
|
||||
PGShmemHeader *hdr;
|
||||
void *origUsedShmemSegAddr = UsedShmemSegAddr;
|
||||
|
||||
Assert(UsedShmemSegAddr != NULL);
|
||||
Assert(IsUnderPostmaster);
|
||||
|
||||
hdr = (PGShmemHeader *) MapViewOfFileEx((HANDLE) UsedShmemSegID, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0, UsedShmemSegAddr);
|
||||
if (!hdr)
|
||||
elog(FATAL, "could not reattach to shared memory (key=%d, addr=%p): %lu",
|
||||
(int) UsedShmemSegID, UsedShmemSegAddr, GetLastError());
|
||||
if (hdr != origUsedShmemSegAddr)
|
||||
elog(FATAL, "reattaching to shared memory returned unexpected address (got %p, expected %p)",
|
||||
hdr, origUsedShmemSegAddr);
|
||||
if (hdr->magic != PGShmemMagic)
|
||||
elog(FATAL, "reattaching to shared memory returned non-PostgreSQL memory");
|
||||
|
||||
UsedShmemSegAddr = hdr; /* probably redundant */
|
||||
}
|
||||
|
||||
/*
|
||||
* PGSharedMemoryDetach
|
||||
*
|
||||
* Detach from the shared memory segment, if still attached. This is not
|
||||
* intended for use by the process that originally created the segment. Rather,
|
||||
* this is for subprocesses that have inherited an attachment and want to
|
||||
* get rid of it.
|
||||
*/
|
||||
void
|
||||
PGSharedMemoryDetach(void)
|
||||
{
|
||||
if (UsedShmemSegAddr != NULL)
|
||||
{
|
||||
if (!UnmapViewOfFile(UsedShmemSegAddr))
|
||||
elog(LOG, "could not unmap view of shared memory: %lu", GetLastError());
|
||||
|
||||
UsedShmemSegAddr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* pgwin32_SharedMemoryDelete(status, shmId) deletes a shared memory segment
|
||||
* (called as an on_shmem_exit callback, hence funny argument list)
|
||||
*/
|
||||
static void
|
||||
pgwin32_SharedMemoryDelete(int status, Datum shmId)
|
||||
{
|
||||
PGSharedMemoryDetach();
|
||||
if (!CloseHandle((HANDLE) DatumGetInt32(shmId)))
|
||||
elog(LOG, "could not close handle to shared memory: %lu", GetLastError());
|
||||
}
|
@ -2,7 +2,7 @@ package Mkvcbuild;
|
||||
#
|
||||
# Package that generates build files for msvc build
|
||||
#
|
||||
# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.3 2007/03/19 09:34:09 mha Exp $
|
||||
# $PostgreSQL: pgsql/src/tools/msvc/Mkvcbuild.pm,v 1.4 2007/03/21 14:39:23 mha Exp $
|
||||
#
|
||||
use Carp;
|
||||
use Win32;
|
||||
@ -58,7 +58,7 @@ sub mkvcbuild
|
||||
$postgres->AddFile('src\backend\utils\fmgrtab.c');
|
||||
$postgres->ReplaceFile('src\backend\port\dynloader.c','src\backend\port\dynloader\win32.c');
|
||||
$postgres->ReplaceFile('src\backend\port\pg_sema.c','src\backend\port\win32_sema.c');
|
||||
$postgres->ReplaceFile('src\backend\port\pg_shmem.c','src\backend\port\sysv_shmem.c');
|
||||
$postgres->ReplaceFile('src\backend\port\pg_shmem.c','src\backend\port\win32_shmem.c');
|
||||
$postgres->AddFiles('src\port',@pgportfiles);
|
||||
$postgres->AddDir('src\timezone');
|
||||
$postgres->AddFiles('src\backend\parser','scan.l','gram.y');
|
||||
|
Loading…
x
Reference in New Issue
Block a user