Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  dsm_registry.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * dsm_registry.c
 *   Functions for interfacing with the dynamic shared memory registry.
 *
 * This provides a way for libraries to use shared memory without needing
 * to request it at startup time via a shmem_request_hook.  The registry
 * stores dynamic shared memory (DSM) segment handles keyed by a
 * library-specified string.
 *
 * The registry is accessed by calling GetNamedDSMSegment().  If a segment
 * with the provided name does not yet exist, it is created and initialized
 * with the provided init_callback callback function.  Otherwise,
 * GetNamedDSMSegment() simply ensures that the segment is attached to the
 * current backend.  This function guarantees that only one backend
 * initializes the segment and that all other backends just attach it.
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 * IDENTIFICATION
 *   src/backend/storage/ipc/dsm_registry.c
 *
 *-------------------------------------------------------------------------
 */


#include "postgres.h"

#include "lib/dshash.h"
#include "storage/dsm_registry.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "utils/memutils.h"

typedef struct DSMRegistryCtxStruct
{
 dsa_handle dsah;
 dshash_table_handle dshh;
} DSMRegistryCtxStruct;

static DSMRegistryCtxStruct *DSMRegistryCtx;

typedef struct DSMRegistryEntry
{
 char  name[64];
 dsm_handle handle;
 size_t  size;
} DSMRegistryEntry;

static const dshash_parameters dsh_params = {
 offsetof(DSMRegistryEntry, handle),
 sizeof(DSMRegistryEntry),
 dshash_strcmp,
 dshash_strhash,
 dshash_strcpy,
 LWTRANCHE_DSM_REGISTRY_HASH
};

static dsa_area *dsm_registry_dsa;
static dshash_table *dsm_registry_table;

Size
DSMRegistryShmemSize(void)
{
 return MAXALIGN(sizeof(DSMRegistryCtxStruct));
}

void
DSMRegistryShmemInit(void)
{
 bool  found;

 DSMRegistryCtx = (DSMRegistryCtxStruct *)
  ShmemInitStruct("DSM Registry Data",
      DSMRegistryShmemSize(),
      &found);

 if (!found)
 {
  DSMRegistryCtx->dsah = DSA_HANDLE_INVALID;
  DSMRegistryCtx->dshh = DSHASH_HANDLE_INVALID;
 }
}

/*
 * Initialize or attach to the dynamic shared hash table that stores the DSM
 * registry entries, if not already done.  This must be called before accessing
 * the table.
 */

static void
init_dsm_registry(void)
{
 /* Quick exit if we already did this. */
 if (dsm_registry_table)
  return;

 /* Otherwise, use a lock to ensure only one process creates the table. */
 LWLockAcquire(DSMRegistryLock, LW_EXCLUSIVE);

 if (DSMRegistryCtx->dshh == DSHASH_HANDLE_INVALID)
 {
  /* Initialize dynamic shared hash table for registry. */
  dsm_registry_dsa = dsa_create(LWTRANCHE_DSM_REGISTRY_DSA);
  dsm_registry_table = dshash_create(dsm_registry_dsa, &dsh_params, NULL);

  dsa_pin(dsm_registry_dsa);
  dsa_pin_mapping(dsm_registry_dsa);

  /* Store handles in shared memory for other backends to use. */
  DSMRegistryCtx->dsah = dsa_get_handle(dsm_registry_dsa);
  DSMRegistryCtx->dshh = dshash_get_hash_table_handle(dsm_registry_table);
 }
 else
 {
  /* Attach to existing dynamic shared hash table. */
  dsm_registry_dsa = dsa_attach(DSMRegistryCtx->dsah);
  dsa_pin_mapping(dsm_registry_dsa);
  dsm_registry_table = dshash_attach(dsm_registry_dsa, &dsh_params,
             DSMRegistryCtx->dshh, NULL);
 }

 LWLockRelease(DSMRegistryLock);
}

/*
 * Initialize or attach a named DSM segment.
 *
 * This routine returns the address of the segment.  init_callback is called to
 * initialize the segment when it is first created.
 */

void *
GetNamedDSMSegment(const char *name, size_t size,
       void (*init_callback) (void *ptr), bool *found)
{
 DSMRegistryEntry *entry;
 MemoryContext oldcontext;
 void    *ret;
 dsm_segment *seg;

 Assert(found);

 if (!name || *name == '\0')
  ereport(ERROR,
    (errmsg("DSM segment name cannot be empty")));

 if (strlen(name) >= offsetof(DSMRegistryEntry, handle))
  ereport(ERROR,
    (errmsg("DSM segment name too long")));

 if (size == 0)
  ereport(ERROR,
    (errmsg("DSM segment size must be nonzero")));

 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
 oldcontext = MemoryContextSwitchTo(TopMemoryContext);

 /* Connect to the registry. */
 init_dsm_registry();

 entry = dshash_find_or_insert(dsm_registry_table, name, found);
 if (!(*found))
 {
  entry->handle = DSM_HANDLE_INVALID;
  entry->size = size;
 }
 else if (entry->size != size)
  ereport(ERROR,
    (errmsg("requested DSM segment size does not match size of existing segment")));

 if (entry->handle == DSM_HANDLE_INVALID)
 {
  *found = false;

  /* Initialize the segment. */
  seg = dsm_create(size, 0);

  if (init_callback)
   (*init_callback) (dsm_segment_address(seg));

  dsm_pin_segment(seg);
  dsm_pin_mapping(seg);
  entry->handle = dsm_segment_handle(seg);
 }
 else
 {
  /* If the existing segment is not already attached, attach it now. */
  seg = dsm_find_mapping(entry->handle);
  if (seg == NULL)
  {
   seg = dsm_attach(entry->handle);
   if (seg == NULL)
    elog(ERROR, "could not map dynamic shared memory segment");

   dsm_pin_mapping(seg);
  }
 }

 ret = dsm_segment_address(seg);
 dshash_release_lock(dsm_registry_table, entry);
 MemoryContextSwitchTo(oldcontext);

 return ret;
}

Messung V0.5 in Prozent
C=93 H=90 G=91

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002