mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-25 00:03:03 +01:00
1591a54e5e
1. Added macros to declare thread entrypoints 2. THD_mutex_* functions use Firebird::Mutex 3. Thread local storage use fb_tls.h
229 lines
5.7 KiB
C++
229 lines
5.7 KiB
C++
/*
|
|
* PROGRAM: JRD Access Method
|
|
* MODULE: dls.cpp
|
|
* DESCRIPTION: Temporary file management
|
|
* The file contains set of functions that
|
|
* are used to manage directory list.
|
|
*
|
|
* 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): ______________________________________.
|
|
*
|
|
* 26-Sept-2001 Paul Beach - External File Directory Config. Parameter
|
|
*/
|
|
|
|
#include "firebird.h"
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "../jrd/sort.h"
|
|
#include "../jrd/dls_proto.h"
|
|
#include "../jrd/gds_proto.h"
|
|
#include "../jrd/gdsassert.h"
|
|
#include "../jrd/file_params.h"
|
|
#include "../common/config/dir_list.h"
|
|
|
|
using namespace Jrd;
|
|
|
|
static mutexed_dir_list DLS_cfg_tmpdir; /* directory list object */
|
|
|
|
/* Note that the only kind of writing permitted on the function_dir_list is
|
|
* appending a new entry to the existing (possibly empty) list.
|
|
* Therefore, we only need a write-lock to protect against
|
|
* simultaneous updates: readers don't need a lock because they'll
|
|
* always see either the old or the new state of the list, never an
|
|
* in-between state.
|
|
*
|
|
* Also note that for this argument to be correct, it is necessary
|
|
* that updaters NULL out the "next" pointer of a new element
|
|
* *before*, not after, they append the element to the list, so that
|
|
* the list is at all times terminated by a NULL pointer.
|
|
*/
|
|
|
|
|
|
bool DLS_get_temp_space(ULONG size, sort_work_file* sfb)
|
|
{
|
|
/**************************************
|
|
*
|
|
* D L S _ g e t _ t e m p _ s p a c e
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Allocate disk space with required size
|
|
*
|
|
**************************************/
|
|
|
|
bool result = false;
|
|
|
|
fb_assert(size > (ULONG) 0);
|
|
fb_assert(sfb);
|
|
|
|
mutexed_dir_list* ptr = DLS_get_access();
|
|
|
|
#ifdef V4_THREADING
|
|
if (!ptr->mdls_mutex_init) {
|
|
V4_MUTEX_INIT(ptr->mdls_mutex);
|
|
ptr->mdls_mutex_init = true;
|
|
}
|
|
|
|
V4_MUTEX_LOCK(ptr->mdls_mutex);
|
|
#endif
|
|
if (!sfb->sfb_dls) {
|
|
/* allocate temp. space starting search from the begining of the dir_list */
|
|
for (sfb->sfb_dls = ptr->mdls_dls;
|
|
sfb->sfb_dls;
|
|
sfb->sfb_dls = sfb->sfb_dls->dls_next)
|
|
{
|
|
if (size <= (sfb->sfb_dls->dls_size - sfb->sfb_dls->dls_inuse)) {
|
|
sfb->sfb_dls->dls_inuse += size;
|
|
result = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
/* allocate temp. space from the current dir_list entry */
|
|
if (size <= (sfb->sfb_dls->dls_size - sfb->sfb_dls->dls_inuse)) {
|
|
sfb->sfb_dls->dls_inuse += size;
|
|
result = true;
|
|
}
|
|
}
|
|
#ifdef V4_THREADING
|
|
V4_MUTEX_UNLOCK(ptr->mdls_mutex);
|
|
#endif
|
|
|
|
return (result);
|
|
}
|
|
|
|
|
|
void DLS_put_temp_space(sort_work_file* sfb)
|
|
{
|
|
/**************************************
|
|
*
|
|
* D L S _ p u t _ t e m p _ s p a c e
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Release disk space occupied by sort file
|
|
*
|
|
**************************************/
|
|
if (sfb && sfb->sfb_dls) {
|
|
mutexed_dir_list* ptr = DLS_get_access();
|
|
#ifdef V4_THREADING
|
|
fb_assert(ptr->mdls_mutex_init);
|
|
V4_MUTEX_LOCK(ptr->mdls_mutex);
|
|
#endif
|
|
fb_assert(sfb->sfb_dls->dls_inuse >= sfb->sfb_file_size);
|
|
if (sfb->sfb_dls->dls_inuse > sfb->sfb_file_size)
|
|
sfb->sfb_dls->dls_inuse -= sfb->sfb_file_size;
|
|
else
|
|
sfb->sfb_dls->dls_inuse = 0;
|
|
#ifdef V4_THREADING
|
|
V4_MUTEX_UNLOCK(ptr->mdls_mutex);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
bool DLS_add_dir(ULONG size, const TEXT* dir_name)
|
|
{
|
|
/**************************************
|
|
*
|
|
* D L S _ a d d _ d i r
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Add new entry to the temporary directory list.
|
|
*
|
|
**************************************/
|
|
|
|
/* allocate dir_list structure */
|
|
|
|
dir_list* new_dls = (dir_list*) gds__alloc((SLONG) (sizeof(dir_list) +
|
|
sizeof(TEXT) * strlen(dir_name)));
|
|
if (!new_dls)
|
|
return false;
|
|
|
|
strcpy(new_dls->dls_directory, dir_name);
|
|
new_dls->dls_size = size;
|
|
new_dls->dls_inuse = 0;
|
|
new_dls->dls_next = NULL;
|
|
|
|
/* get access to directory list object */
|
|
|
|
mutexed_dir_list* mdls = DLS_get_access();
|
|
|
|
#ifdef V4_THREADING
|
|
/* lock mutex, initialize it in case of the first access */
|
|
|
|
if (!mdls->mdls_mutex_init) {
|
|
V4_MUTEX_INIT(mdls->mdls_mutex);
|
|
mdls->mdls_mutex_init = true;
|
|
}
|
|
|
|
V4_MUTEX_LOCK(mdls->mdls_mutex);
|
|
#endif
|
|
|
|
/* add new entry to the end of list */
|
|
|
|
if (!mdls->mdls_dls) {
|
|
mdls->mdls_dls = new_dls;
|
|
}
|
|
else {
|
|
dir_list* dls_iterator = mdls->mdls_dls;
|
|
while (dls_iterator->dls_next)
|
|
dls_iterator = dls_iterator->dls_next;
|
|
dls_iterator->dls_next = new_dls;
|
|
}
|
|
|
|
#ifdef V4_THREADING
|
|
/* release lock */
|
|
|
|
V4_MUTEX_UNLOCK(mdls->mdls_mutex);
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
mutexed_dir_list* DLS_get_access(void)
|
|
{
|
|
/**************************************
|
|
*
|
|
* D L S _ g e t _ a c c e s s
|
|
*
|
|
**************************************
|
|
*
|
|
* Functional description
|
|
* Return pointer to the temporary file configuration
|
|
*
|
|
**************************************/
|
|
|
|
static bool is_initialized = false;
|
|
if (!is_initialized) {
|
|
is_initialized = true;
|
|
Firebird::TempDirectoryList dir_list;
|
|
for (int i = 0; i < dir_list.Count(); i++) {
|
|
DLS_add_dir(dir_list[i].second, dir_list[i].first.c_str());
|
|
}
|
|
}
|
|
|
|
return (&DLS_cfg_tmpdir);
|
|
}
|
|
|