2N/A * See the file LICENSE for redistribution information. 2N/A * Copyright (c) 1996, 1997, 1998 2N/A * Sleepycat Software. All rights reserved. 2N/A#
endif /* not lint */ 2N/A * Open a backing file for the memory pool. 2N/A /* Validate arguments. */ 2N/A /* Require a non-zero pagesize. */ 2N/A * Open a backing file for the memory pool; internal version. 2N/A * PUBLIC: int __memp_fopen __P((DB_MPOOL *, MPOOLFILE *, const char *, * PUBLIC: u_int32_t, int, size_t, int, DB_MPOOL_FINFO *, DB_MPOOLFILE **)); * If mfp is provided, we take the DB_MPOOL_FINFO information from * the mfp. We don't bother initializing everything, because some * of them are expensive to acquire. If no mfp is provided and the * finfop argument is NULL, we default the values. /* Allocate and initialize the per-process structure. */ "memp_fopen: temporary files can't be readonly");
/* Get the real name for this file and open it. */ * Don't permit files that aren't a multiple of the pagesize, * and find the number of the last page in the file, all the * time being careful not to overflow 32 bits. * We can't use off_t's here, or in any code in the mainline * library for that matter. (We have to use them in the os * stubs, of course, as there are system calls that take them * as arguments.) The reason is that some customers build in * environments where an off_t is 32-bits, but still run where * offsets are 64-bits, and they pay us a lot of money. /* Page sizes have to be a power-of-two, ignore mbytes. */ "%s: file size not a multiple of the pagesize",
/* Correction: page numbers are zero-based, not 1-based. */ * Get the file id if we weren't given one. Generated file id's * don't use timestamps, otherwise there'd be no chance of any * other process joining the party. * If we weren't provided an underlying shared object to join with, * find/allocate the shared file objects. Also allocate space for * for the per-process thread lock. * + the DB_NOMMAP flag wasn't set * + and is less than mp_mmapsize bytes in size * checking based on the mmap call failure. We want to do normal I/O * on the file if the reason we failed was because the file was on an * NFS mounted partition, and we can fail in buffer I/O just as easily * We'd like to test to see if the file is too big to mmap. Since we * don't know what size or type off_t's or size_t's are, or the largest * unsigned integral type is, or what random insanity the local C * compiler will perpetrate, doing the comparison in a portable way is * flatly impossible. Hope that mmap fails if the file is too large. * Note that we do not have to free the thread mutex, because we * never get to here after we have successfully allocated it. * Walk the list of MPOOLFILE's, looking for a matching file. * Temporary files can't match previous files. "%s: ftype, clear length or pagesize changed",
/* Found it: increment the reference count. */ /* Allocate a new MPOOLFILE. */ /* Initialize the structure. */ * If the user specifies DB_MPOOL_LAST or DB_MPOOL_NEW on a memp_fget, * we have to know the last page in the file. Figure it out and save /* Copy the file path into shared memory. */ /* Copy the file identification string into shared memory. */ /* Copy the page cookie into shared memory. */ /* Prepend the MPOOLFILE to the list of MPOOLFILE's. */ * Close a backing file for the memory pool. * We have to reference count DB_MPOOLFILE structures as other * threads may be using them. The problem only happens if the * application makes a bad design choice. Here's the path: * Thread A opens a database. * Thread B uses thread A's DB_MPOOLFILE to write a buffer * in order to free up memory in the mpool cache. * Thread A closes the database while thread B is using the * DB_MPOOLFILE structure. * By opening all databases before creating the threads, and * closing them after the threads have exited, applications * get better performance and avoid the problem path entirely. * Regardless, holding the DB_MPOOLFILE to flush a dirty buffer * is a short-term lock, even in worst case, since we better be * the only thread of control using the DB_MPOOLFILE structure * to read pages *into* the cache. Wait until we're the only * reference holder and remove the DB_MPOOLFILE structure from * the list, so nobody else can even find it. /* Complain if pinned blocks never returned. */ /* Close the underlying MPOOLFILE. */ /* Discard any mmap information. */ /* Close the file; temporary files may not yet have been created. */ /* Discard the DB_MPOOLFILE structure. */ * Close down an MPOOLFILE. /* If more than a single reference, simply decrement. */ * Move any BH's held by the file to the free list. We don't free the * memory itself because we may be discarding the memory pool, and it's * fairly expensive to reintegrate the buffers back into the region for /* Complain if we find any blocks that were left dirty. */ "%s: close: pgno %lu left dirty; ref %lu",
/* Delete from the list of MPOOLFILEs. */