mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 20:43:04 +01:00
Cleanup unix shmat() - not needed any more for any OS
This commit is contained in:
parent
4f8f8ef534
commit
ddbaf00cf9
@ -109,9 +109,7 @@ static int process_id;
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FTOK_KEY 15
|
#define FTOK_KEY 15
|
||||||
#define PRIV 0666
|
#define PRIV 0666
|
||||||
@ -172,12 +170,6 @@ static bool event_blocked(const event_t* event, const SLONG value);
|
|||||||
static void longjmp_sig_handler(int);
|
static void longjmp_sig_handler(int);
|
||||||
static GlobalPtr<Mutex> openFdInit;
|
static GlobalPtr<Mutex> openFdInit;
|
||||||
|
|
||||||
#ifndef HAVE_MMAP
|
|
||||||
static SLONG find_key(ISC_STATUS*, const TEXT*);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
// File lock holder
|
// File lock holder
|
||||||
@ -700,8 +692,6 @@ int Sys5Semaphore::getId()
|
|||||||
}
|
}
|
||||||
#endif // USE_SYS5SEMAPHORE
|
#endif // USE_SYS5SEMAPHORE
|
||||||
|
|
||||||
#endif // HAVE_MMAP
|
|
||||||
|
|
||||||
#endif // UNIX
|
#endif // UNIX
|
||||||
|
|
||||||
#if defined(WIN_NT)
|
#if defined(WIN_NT)
|
||||||
@ -1691,27 +1681,6 @@ void ISC_remove_map_file(const TEXT* filename)
|
|||||||
{
|
{
|
||||||
TEXT expanded_filename[MAXPATHLEN];
|
TEXT expanded_filename[MAXPATHLEN];
|
||||||
gds__prefix_lock(expanded_filename, filename);
|
gds__prefix_lock(expanded_filename, filename);
|
||||||
#if defined(UNIX) && (!defined(HAVE_MMAP))
|
|
||||||
key_t key = 0;
|
|
||||||
|
|
||||||
Firebird::AutoPtr<FILE, Firebird::FileClose> fp(fopen(expanded_filename, "r"));
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
Firebird::string s;
|
|
||||||
s.LoadFromFile(fp);
|
|
||||||
key = atoi(s.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (key)
|
|
||||||
{
|
|
||||||
int shmid = shmget(key, 0, 0);
|
|
||||||
if (shmid > 0)
|
|
||||||
{
|
|
||||||
shmid_ds dummy;
|
|
||||||
shmctl(shmid, IPC_RMID, &dummy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We can't do much (specially in dtors) when it fails
|
// We can't do much (specially in dtors) when it fails
|
||||||
// therefore do not check for errors - at least it's just /tmp.
|
// therefore do not check for errors - at least it's just /tmp.
|
||||||
@ -1720,8 +1689,6 @@ void ISC_remove_map_file(const TEXT* filename)
|
|||||||
|
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
|
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
|
|
||||||
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
||||||
const TEXT* filename,
|
const TEXT* filename,
|
||||||
FPTR_INIT_GLOBAL_REGION init_routine,
|
FPTR_INIT_GLOBAL_REGION init_routine,
|
||||||
@ -1934,330 +1901,6 @@ UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // no HAVE_MMAP
|
|
||||||
|
|
||||||
static bool setSharedMemoryAccessRights(ISC_STATUS* status_vector, SLONG shmid)
|
|
||||||
{
|
|
||||||
char secDb[MAXPATHLEN];
|
|
||||||
SecurityDatabase::getPath(secDb);
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
if (stat(secDb, &st) == 0)
|
|
||||||
{
|
|
||||||
shmid_ds ds;
|
|
||||||
ds.shm_perm.uid = geteuid() == 0 ? st.st_uid : geteuid();
|
|
||||||
ds.shm_perm.gid = st.st_gid;
|
|
||||||
ds.shm_perm.mode = st.st_mode;
|
|
||||||
if (shmctl(shmid, IPC_SET, &ds) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmctl", errno);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
UCHAR* ISC_map_file(ISC_STATUS* status_vector,
|
|
||||||
const TEXT* filename,
|
|
||||||
FPTR_INIT_GLOBAL_REGION init_routine,
|
|
||||||
void* init_arg,
|
|
||||||
ULONG length,
|
|
||||||
sh_mem* shmem_data)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* I S C _ m a p _ f i l e ( U N I X - s h m a t )
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Try to map a given file. If we are the first (i.e. only)
|
|
||||||
* process to map the file, call a given initialization
|
|
||||||
* routine (if given) or punt (leaving the file unmapped).
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
TEXT expanded_filename[MAXPATHLEN];
|
|
||||||
gds__prefix_lock(expanded_filename, filename);
|
|
||||||
|
|
||||||
bool init_flag = false;
|
|
||||||
|
|
||||||
/* Produce shared memory key for file */
|
|
||||||
|
|
||||||
const SLONG key = find_key(status_vector, expanded_filename);
|
|
||||||
if (!key) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write shared memory key into expanded_filename file */
|
|
||||||
|
|
||||||
MutexLockGuard guard(openFdInit);
|
|
||||||
|
|
||||||
const int fd = os_utils::openCreateSharedFile(expanded_filename, O_TRUNC);
|
|
||||||
if (fd < 0)
|
|
||||||
{
|
|
||||||
error(status_vector, "open", errno);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE* const fp = fdopen(fd, "w");
|
|
||||||
if (!fp)
|
|
||||||
{
|
|
||||||
error(status_vector, "fdopen", errno);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(fp, "%"SLONGFORMAT, key);
|
|
||||||
|
|
||||||
/* Get an exclusive lock on the file until the initialization process
|
|
||||||
is complete. That way potential race conditions are avoided. */
|
|
||||||
|
|
||||||
#ifndef HAVE_FLOCK
|
|
||||||
if (lockf(fd, F_LOCK, 0)) {
|
|
||||||
error(status_vector, "lockf", errno);
|
|
||||||
#else
|
|
||||||
if (flock(fd, LOCK_EX)) {
|
|
||||||
error(status_vector, "flock", errno);
|
|
||||||
#endif
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the shared memory region if it doesn't already exist. */
|
|
||||||
|
|
||||||
struct shmid_ds buf;
|
|
||||||
SLONG shmid = shmget(key, length, IPC_CREAT | IPC_EXCL | PRIV);
|
|
||||||
if (shmid == -1) {
|
|
||||||
shmid = shmget(key, length, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!setSharedMemoryAccessRights(status_vector, shmid))
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shmid == -1)
|
|
||||||
{
|
|
||||||
#ifdef SUPERSERVER
|
|
||||||
if (errno == EINVAL)
|
|
||||||
{
|
|
||||||
/* There are two cases when shmget() returns EINVAL error:
|
|
||||||
|
|
||||||
- "length" is less than the system-imposed minimum or
|
|
||||||
greater than the system-imposed maximum.
|
|
||||||
|
|
||||||
- A shared memory identifier exists for "key" but the
|
|
||||||
size of the segment associated with it is less
|
|
||||||
than "length" and "length" is not equal to zero.
|
|
||||||
|
|
||||||
Let's find out what the problem is by getting the
|
|
||||||
system-imposed limits.
|
|
||||||
|
|
||||||
If we are here then the shared memory segment already
|
|
||||||
exists and the "length" we specified in shmget() is
|
|
||||||
bigger than the size of the existing segment.
|
|
||||||
|
|
||||||
Because the segment has to exist at this point the
|
|
||||||
following shmget() does not have IPC_CREAT flag set.
|
|
||||||
|
|
||||||
We need to get shmid to delete the segment. Because we
|
|
||||||
do not know the size of the existing segment the easiest
|
|
||||||
way to get shmid is to attach to the segment with zero
|
|
||||||
length
|
|
||||||
*/
|
|
||||||
if ((shmid = shmget(key, 0, 0)) == -1)
|
|
||||||
{
|
|
||||||
string msg;
|
|
||||||
msg.printf("shmget(0x%x, 0, 0)", key);
|
|
||||||
error(status_vector, msg.c_str(), errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shmctl(shmid, IPC_RMID, &buf) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmctl/IPC_RMID", errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have just deleted shared memory segment and current
|
|
||||||
code fragment is an atomic operation (we are holding an
|
|
||||||
exclusive lock on the "isc_lock1.<machine>" file), so
|
|
||||||
we use IPC_EXCL flag to get an error if by some miracle
|
|
||||||
the sagment with the same key is already exists
|
|
||||||
*/
|
|
||||||
if ((shmid = shmget(key, length, IPC_CREAT | IPC_EXCL | PRIV)) == -1)
|
|
||||||
{
|
|
||||||
string msg;
|
|
||||||
msg.printf("shmget(0x%x, %d, IPC_CREAT | IPC_EXCL | PRIV)", key, length);
|
|
||||||
error(status_vector, msg.c_str(), errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!setSharedMemoryAccessRights(status_vector, shmid))
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* if errno != EINVAL) */
|
|
||||||
#endif /* SUPERSERVER */
|
|
||||||
{
|
|
||||||
string msg;
|
|
||||||
msg.printf("shmget(0x%x, %d, 0)", key, length);
|
|
||||||
error(status_vector, msg.c_str(), errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SUPERSERVER
|
|
||||||
/* If we are here there are two possibilities:
|
|
||||||
|
|
||||||
1. we mapped the shared memory segment of the "length" size;
|
|
||||||
2. we mapped the segment of the size less than "length" (but
|
|
||||||
not zero length and bigger than system-imposed minimum);
|
|
||||||
|
|
||||||
We want shared memory segment exactly of the "length" size.
|
|
||||||
Let's find out what the size of the segment is and if it is
|
|
||||||
bigger than length, we remove it and create new one with the
|
|
||||||
size "length".
|
|
||||||
Also, if "length" is zero (that means we have already mapped
|
|
||||||
the existing segment with the zero size) remap the segment
|
|
||||||
with the existing size
|
|
||||||
*/
|
|
||||||
if (shmctl(shmid, IPC_STAT, &buf) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmctl/IPC_STAT", errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
fb_assert(length <= buf.shm_segsz);
|
|
||||||
if (length < buf.shm_segsz)
|
|
||||||
{
|
|
||||||
if (length)
|
|
||||||
{
|
|
||||||
if (shmctl(shmid, IPC_RMID, &buf) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmctl/IPC_RMID", errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((shmid = shmget(key, length, IPC_CREAT | IPC_EXCL | PRIV)) == -1)
|
|
||||||
{
|
|
||||||
string msg;
|
|
||||||
msg.printf("shmget(0x%x, %d, IPC_CREAT | IPC_EXCL | PRIV)", key, length);
|
|
||||||
error(status_vector, msg.c_str(), errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (!setSharedMemoryAccessRights(status_vector, shmid))
|
|
||||||
{
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = buf.shm_segsz;
|
|
||||||
if ((shmid = shmget(key, length, 0)) == -1)
|
|
||||||
{
|
|
||||||
string msg;
|
|
||||||
msg.printf("shmget(0x%x, %d, 0)", key, length);
|
|
||||||
error(status_vector, msg.c_str(), errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#else /* !SUPERSERVER */
|
|
||||||
|
|
||||||
if (length == 0)
|
|
||||||
{
|
|
||||||
/* Use the existing length. This should not happen for the
|
|
||||||
very first attachment to the shared memory. */
|
|
||||||
|
|
||||||
if (shmctl(shmid, IPC_STAT, &buf) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmctl/IPC_STAT", errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
length = buf.shm_segsz;
|
|
||||||
|
|
||||||
/* Now remap with the new-found length */
|
|
||||||
|
|
||||||
if ((shmid = shmget(key, length, 0)) == -1)
|
|
||||||
{
|
|
||||||
string msg;
|
|
||||||
msg.printf("shmget(0x%x, %d, 0)", key, length);
|
|
||||||
error(status_vector, msg.c_str(), errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* SUPERSERVER */
|
|
||||||
|
|
||||||
|
|
||||||
UCHAR* const address = (UCHAR*) shmat(shmid, NULL, 0);
|
|
||||||
if ((IPTR) address == (IPTR) -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmat", errno);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shmctl(shmid, IPC_STAT, &buf) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "shmctl/IPC_STAT", errno);
|
|
||||||
shmdt(address);
|
|
||||||
fclose(fp);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get semaphore for mutex */
|
|
||||||
|
|
||||||
|
|
||||||
/* If we're the only one with shared memory mapped, see if
|
|
||||||
we can initialize it. If we can't, return failure. */
|
|
||||||
|
|
||||||
if (buf.shm_nattch == 1)
|
|
||||||
{
|
|
||||||
if (!init_routine)
|
|
||||||
{
|
|
||||||
shmdt(address);
|
|
||||||
fclose(fp);
|
|
||||||
Arg::Gds(isc_unavailable).copyTo(status_vector);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
buf.shm_perm.mode = 0660;
|
|
||||||
shmctl(shmid, IPC_SET, &buf);
|
|
||||||
init_flag = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
shmem_data->sh_mem_address = address;
|
|
||||||
shmem_data->sh_mem_length_mapped = length;
|
|
||||||
shmem_data->sh_mem_handle = shmid;
|
|
||||||
|
|
||||||
if (init_routine)
|
|
||||||
(*init_routine) (init_arg, shmem_data, init_flag);
|
|
||||||
|
|
||||||
/* When the mapped file is closed here, the lock we applied for
|
|
||||||
synchronization will be released. */
|
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
#endif // HAVE_MMAP
|
|
||||||
|
|
||||||
#endif // UNIX
|
#endif // UNIX
|
||||||
|
|
||||||
|
|
||||||
@ -2660,7 +2303,7 @@ void ISC_unmap_object(ISC_STATUS* status_vector,
|
|||||||
*object_pointer = NULL;
|
*object_pointer = NULL;
|
||||||
return; // true;
|
return; // true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // HAVE_MMAP
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
@ -3511,8 +3154,8 @@ UCHAR *ISC_remap_file(ISC_STATUS* status_vector,
|
|||||||
|
|
||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // HAVE_MMAP
|
||||||
#endif
|
#endif // UNIX
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
@ -3690,7 +3333,6 @@ void ISC_sync_signals_reset()
|
|||||||
#endif // UNIX
|
#endif // UNIX
|
||||||
|
|
||||||
#ifdef UNIX
|
#ifdef UNIX
|
||||||
#ifdef HAVE_MMAP
|
|
||||||
void ISC_unmap_file(ISC_STATUS* status_vector, sh_mem* shmem_data)
|
void ISC_unmap_file(ISC_STATUS* status_vector, sh_mem* shmem_data)
|
||||||
{
|
{
|
||||||
/**************************************
|
/**************************************
|
||||||
@ -3727,30 +3369,6 @@ void ISC_unmap_file(ISC_STATUS* status_vector, sh_mem* shmem_data)
|
|||||||
close(shmem_data->sh_mem_handle);
|
close(shmem_data->sh_mem_handle);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef UNIX
|
|
||||||
#ifndef HAVE_MMAP
|
|
||||||
void ISC_unmap_file(ISC_STATUS* status_vector, sh_mem* shmem_data)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* I S C _ u n m a p _ f i l e ( U N I X - s h m a t )
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Detach from the shared memory
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
//struct shmid_ds buf;
|
|
||||||
//union semun arg;
|
|
||||||
|
|
||||||
shmdt(shmem_data->sh_mem_address);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN_NT
|
#ifdef WIN_NT
|
||||||
@ -3910,42 +3528,6 @@ void longjmp_sig_handler(int sig_num)
|
|||||||
siglongjmp(*TLS_GET(sigjmp_ptr), sig_num);
|
siglongjmp(*TLS_GET(sigjmp_ptr), sig_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_MMAP
|
|
||||||
static SLONG find_key(ISC_STATUS* status_vector, const TEXT* filename)
|
|
||||||
{
|
|
||||||
/**************************************
|
|
||||||
*
|
|
||||||
* f i n d _ k e y
|
|
||||||
*
|
|
||||||
**************************************
|
|
||||||
*
|
|
||||||
* Functional description
|
|
||||||
* Find the semaphore/shared memory key for a file.
|
|
||||||
*
|
|
||||||
**************************************/
|
|
||||||
|
|
||||||
// Produce shared memory key for file
|
|
||||||
|
|
||||||
key_t key = ftok(filename, FTOK_KEY);
|
|
||||||
if (key == -1)
|
|
||||||
{
|
|
||||||
int fd = os_utils::openCreateSharedFile(filename, O_TRUNC);
|
|
||||||
if (fd == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "open", errno);
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
if ((key = ftok(filename, FTOK_KEY)) == -1)
|
|
||||||
{
|
|
||||||
error(status_vector, "ftok", errno);
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return key;
|
|
||||||
}
|
|
||||||
#endif // HAVE_MMAP
|
|
||||||
#endif // UNIX
|
#endif // UNIX
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user