XRootD
Loading...
Searching...
No Matches
XrdSsiShMam Class Reference

#include <XrdSsiShMam.hh>

+ Inheritance diagram for XrdSsiShMam:
+ Collaboration diagram for XrdSsiShMam:

Public Types

enum  LockType {
  ROLock = 0 ,
  RWLock = 1
}
 

Public Member Functions

 XrdSsiShMam (XrdSsiShMat::NewParms &parms)
 
 ~XrdSsiShMam ()
 
bool AddItem (void *newdata, void *olddata, const char *key, int hash, bool replace=false)
 
bool Attach (int tout, bool isrw=false)
 
bool Create (XrdSsiShMat::CRZParms &parms)
 
bool DelItem (void *data, const char *key, int hash)
 
void Detach ()
 Detach the map from the shared memory.
 
bool Enumerate (void *&jar)
 
bool Enumerate (void *&jar, char *&key, void *&val)
 
bool Export ()
 
bool GetItem (void *data, const char *key, int hash)
 
int Info (const char *vname, char *buff=0, int blen=0)
 
bool Resize (XrdSsiShMat::CRZParms &parms)
 
bool Sync ()
 
bool Sync (bool dosync, bool syncdo)
 
bool Sync (int syncqsz)
 
- Public Member Functions inherited from XrdSsiShMat
 XrdSsiShMat (NewParms &parms)
 Constructor (arguments the same as for New())
 
virtual ~XrdSsiShMat ()
 Destructor. Warning, your destructor should call your own Detach()!
 
virtual bool AddItem (void *newdata, void *olddata, const char *key, int hash=0, bool replace=false)=0
 
virtual bool Attach (int tout, bool isrw=false)=0
 
virtual bool Create (CRZParms &parms)=0
 
virtual bool DelItem (void *data, const char *key, int hash=0)=0
 
virtual void Detach ()=0
 Detach the map from the shared memory.
 
virtual bool Enumerate (void *&jar)=0
 
virtual bool Enumerate (void *&jar, char *&key, void *&val)=0
 
virtual bool Export ()=0
 
virtual bool GetItem (void *data, const char *key, int hash=0)=0
 
virtual int Info (const char *vname, char *buff=0, int blen=0)=0
 
virtual bool Resize (CRZParms &parms)=0
 
virtual bool Sync ()=0
 
virtual bool Sync (bool dosync, bool syncdo=false)=0
 
virtual bool Sync (int synqsz)=0
 

Additional Inherited Members

- Static Public Member Functions inherited from XrdSsiShMat
static XrdSsiShMatNew (NewParms &parms)
 
- Protected Attributes inherited from XrdSsiShMat
int shmHash
 
char * shmImpl
 
char * shmPath
 
char * shmType
 
int shmTypeSz
 

Detailed Description

Definition at line 37 of file XrdSsiShMam.hh.

Member Enumeration Documentation

◆ LockType

Enumerator
ROLock 
RWLock 

Definition at line 75 of file XrdSsiShMam.hh.

75{ROLock= 0, RWLock = 1};

Constructor & Destructor Documentation

◆ XrdSsiShMam()

XrdSsiShMam::XrdSsiShMam ( XrdSsiShMat::NewParms parms)

Definition at line 218 of file XrdSsiShMam.cc.

218 : XrdSsiShMat(parms)
219{
220
221// Initialize common stuff
222//
223 shmTemp = 0;
224 shmSize = 0;
225 shmBase = 0;
226 shmFD =-1;
227 timeOut =-1;
228 lkCount = 0;
229 syncLast = 0;
230 syncOpt = 0;
231 syncQWR = 0;
232 syncQSZ = 0;
233 syncOn = false;
234 syncBase = false;
235 isRW = false;
236 lockRO = true;
237 lockRW = true;
238 reUse = false;
239 useAtomic = true;
240
241// Initialize r/w mutexes
242//
243 pthread_mutex_init(&lkMutex, NULL);
244 pthread_rwlock_init(&myMutex, NULL);
245}

◆ ~XrdSsiShMam()

XrdSsiShMam::~XrdSsiShMam ( )
inline

Definition at line 70 of file XrdSsiShMam.hh.

70 {Detach();
71 pthread_mutex_destroy(&lkMutex);
72 pthread_rwlock_destroy(&myMutex);
73 }
void Detach()
Detach the map from the shared memory.

References Detach().

+ Here is the call graph for this function:

Member Function Documentation

◆ AddItem()

bool XrdSsiShMam::AddItem ( void *  newdata,
void *  olddata,
const char *  key,
int  hash,
bool  replace = false 
)
virtual

Add an item to the shared memory table.

Parameters
newdataPointer to the data to be added.
olddataPointer to the area where the replaced data, if any, is to be placed.
keyThe key associated with the data that is to be added.
hashThe hash of the key that is to be used to lookup the key. If the value is zero, an internal hash is computed.
replaceWhen true, if the key exists, the data associated with the key is replaced. When false, if the key exists, the addition fails with errno set to EEXIST.
Returns
true The addition/replacement succeeded. If the key was actually replaced errno is set to EEXIST else it is set to 0.
false The addition/replacement failed; errno indicates reason.

Implements XrdSsiShMat.

Definition at line 251 of file XrdSsiShMam.cc.

253{
254 XLockHelper lockInfo(this, RWLock);
255 MemItem *theItem, *prvItem, *newItem;
256 int hEnt, kLen, iOff, retEno = 0;
257
258// Make sure we can allocate a new item
259//
260 if (!shmSize) {errno = ENOTCONN; return false;}
261 if (!isRW) {errno = EROFS; return false;}
262
263// Verify key length
264//
265 kLen = strlen(key);
266 if (kLen > maxKLen) {errno = ENAMETOOLONG; return false;}
267
268// Check if we need to remap this memory (atomic tests is not needed here).
269// We need to do this prior to file locking as the requirements may change.
270//
271 if (verNum != SHMINFO(verNum)) ReMap(RWLock);
272
273// Lock the file if we have multiple writers or recycling items
274//
275 if (lockRW && !lockInfo.FLock()) return false;
276
277// First try to find the item
278//
279 hEnt = Find(theItem, prvItem, key, hash);
280
281// If we found it then see if we can replace it. If so and we can reuse the
282// the item, then just update the data portion. Otherwise, we need to get a
283// new item and replace the existing item.
284//
285 if (hEnt)
286 {if (olddata) memcpy(olddata, ITEM_VAL(theItem), shmTypeSz);
287 if (!replace) {errno = EEXIST; return false;}
288 if (reUse)
289 {memcpy(ITEM_VAL(theItem), newdata, shmTypeSz);
290 if (syncOn) Updated(ITEM_VOF(theItem), shmTypeSz);
291 errno = EEXIST;
292 return true;
293 }
294 retEno = EEXIST;
295 }
296
297// Get a new item
298//
299 if (!(newItem = NewItem())) {errno = ENOSPC; return false;}
300
301// Construct the new item
302//
303 newItem->hash = hash;
304 memcpy(ITEM_VAL(newItem), newdata, shmTypeSz);
305 strcpy(ITEM_KEY(newItem), key);
306
307// If we are replacing an item then We need to bridge over the item we are
308// replacing in a way that doesn't make the item disappear for other readers.
309// Otherwise, we can patch in the new item either on the last item in the chain
310// or directly off the table. Note that releasing the lock creates a memory
311// fence. To understand why this this works consider the relationship between:
312// hEnt prvItem The state of the table
313// 0 0 Not found because index table slot is zero
314// 0 !0 Not found in a chain of items, prvItem is the last one
315// !0 0 Was found and is the first or only item in the chain
316// !0 !0 Was found and is in the middle or end of the chain
317//
318//
319 if (hEnt) Atomic_SET(newItem->next, theItem->next); // Atomic
320 else {hEnt = (unsigned int)hash % shmSlots;
321 if (hEnt == 0) hEnt = 1;
322 SHMINFO(itemCount)++;
323 }
324
325 iOff = SHMOFFS(newItem);
326 if (prvItem) Atomic_SET_STRICT(prvItem->next, iOff); // Atomic
327 else {SHMINFO(slotsUsed)++;
328 Atomic_SET_STRICT(shmIndex[hEnt],iOff); // Atomic
329 if (syncOn) Updated(SHMOFFS(&shmIndex[hEnt]));
330 }
331
332// Indicate which things we changed if we have syncing
333//
334 if (syncOn)
335 {Updated(0);
336 Updated(SHMOFFS(newItem));
337 if (prvItem) Updated(SHMOFFS(prvItem));
338 }
339
340// All done, return result
341//
342 errno = retEno;
343 return true;
344}
#define Atomic_SET(x, y)
#define SHMOFFS(addr)
#define ITEM_VOF(x)
#define SHMINFO(x)
#define ITEM_KEY(x)
#define ITEM_VAL(x)

References Atomic_SET, ITEM_KEY, ITEM_VAL, ITEM_VOF, RWLock, SHMINFO, SHMOFFS, and XrdSsiShMat::shmTypeSz.

Referenced by Resize().

+ Here is the caller graph for this function:

◆ Attach()

bool XrdSsiShMam::Attach ( int  tout,
bool  isrw = false 
)
virtual

Attach this object to the shared memory associated with this object at creation time (see New() method). The attach operation waits until the shared memory file is available. At that time, the file is memory mapped.

Parameters
toutThe maximum number of seconds to wait for the shared memory file to become available. If tout is zero, then the file must be immediately available. If the value is negative then the attach waits as long as needed. When tout is reached the attach fails with errno set to ETIMEDOUT.
isrwWhen true the file is mapped to writable memory and allows updates to the table. If false, the shared memory is made read/only and may be significantly faster to access.
Returns
true - The shared memory was attached, the table can be used.
false - The shared memory could not be attached, errno holds reason.

Implements XrdSsiShMat.

Definition at line 350 of file XrdSsiShMam.cc.

351{
352 FileHelper fileHelp(this);
353 XLockHelper lockInfo(this, (isrw ? RWLock : ROLock));
354 struct stat Stat1, Stat2;
355 int mMode, oMode;
356 union {int *intP; Atomic(int) *antP;} xntP;
357
358// Compute open and mmap options
359//
360 if (isrw)
361 {oMode = O_RDWR;
362 mMode = PROT_READ|PROT_WRITE;
363 isRW = true;
364 } else {
365 oMode = O_RDONLY;
366 mMode = PROT_READ;
367 isRW = false;
368 }
369
370// Attempt to open the file
371//
372 timeOut = tout;
373 if (tout < 0) tout = 0x7fffffff;
374 while((shmFD = ShMam_Open(shmPath, oMode)) < 0 && tout >= 0)
375 {if (errno != ENOENT) return false;
376 if (!tout) break;
377 Snooze(3);
378 tout -= 3;
379 }
380
381// Test if we timed out
382//
383 if (tout <= 0) {errno = ETIMEDOUT; return false;}
384 fileHelp.autoClose = true;
385
386// Lock this file as we don't want it changing on us for now
387//
388 if (!lockInfo.FLock()) return false;
389
390// Get the stat information for this file
391//
392 if (fstat(shmFD, &Stat1)) return false;
393
394// The file is open, try to memory map it
395//
396 shmBase = (char *)mmap(0, Stat1.st_size, mMode, MAP_SHARED, shmFD, 0);
397 if (shmBase == MAP_FAILED) return false;
398 shmSize = Stat1.st_size;
399
400// Make sure we have a valid hash name
401//
402 if (!shmHash) memcpy(&shmHash, "c32 ", sizeof(int));
403
404// Verify tha the objects in this mapping are compatible with this object
405//
406 if (SHMINFO(typeSz) != shmTypeSz || strcmp(shmType, SHMINFO(typeID))
407 || strcmp(shmImpl, SHMINFO(myName)) || shmHash != SHMINFO(hashID))
408 {errno = EDOM; return false;}
409
410// Copy out the information we can use locally
411//
412 verNum = SHMINFO(verNum);
413 keyPos = SHMINFO(keyPos);
414 maxKLen = SHMINFO(maxKeySz);
415 xntP.intP = SHMADDR(int, SHMINFO(index)); shmIndex = xntP.antP;
416 shmSlots = SHMINFO(slots);
417 shmItemSz = SHMINFO(itemSz);
418 shmInfoSz = SHMINFO(infoSz);
419
420// Now, there is a loophole here as the file could have been exported while
421// we were trying to attach it. If this happened, the inode would change.
422// We test for this now. If it changed, tell the caller to try again.
423//
424 if (stat(shmPath, &Stat2)
425 || Stat1.st_dev != Stat2.st_dev || Stat1.st_ino != Stat2.st_ino)
426 {errno = EAGAIN; return false;}
427 accMode = Stat2.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO);
428
429// Set locking based on how the table was created
430//
431 SetLocking(isrw);
432 fileHelp.autoClose = false;
433 return true;
434}
#define fstat(a, b)
Definition XrdPosix.hh:57
#define stat(a, b)
Definition XrdPosix.hh:96
#define Atomic(type)
#define SHMADDR(type, offs)

References Atomic, fstat, ROLock, RWLock, SHMADDR, XrdSsiShMat::shmHash, XrdSsiShMat::shmImpl, SHMINFO, XrdSsiShMat::shmPath, XrdSsiShMat::shmType, XrdSsiShMat::shmTypeSz, and stat.

◆ Create()

bool XrdSsiShMam::Create ( XrdSsiShMat::CRZParms parms)
virtual

Implements XrdSsiShMat.

Definition at line 440 of file XrdSsiShMam.cc.

441{
442 static const int minInfoSz = 256;
443 static const int okMode = S_IRWXU|S_IRWXG|S_IROTH;
444 static const int crMode = S_IRWXU|S_IRWXG|S_IROTH;
445 FileHelper fileHelp(this);
446 ShmInfo theInfo;
447 int n, maxEnts, totSz, indexSz;
448 union {int *intP; Atomic(int) *antP;} xntP;
449
450// Validate parameter list values
451//
452 if (parms.indexSz <= 0 || parms.maxKeys <= 0 || parms.maxKLen <= 0)
453 {errno = EINVAL; return false;}
454 if (parms.mode & ~okMode || ((parms.mode & crMode) != crMode))
455 {errno = EACCES; return false;}
456
457// We need the reuse and multw options later so calclulate them now
458//
459 reUse = (parms.reUse <= 0 ? false : true);
460 multW = (parms.multW <= 0 ? false : true);
461
462// Clear the memory segment information we will be constructing
463//
464 memset(&theInfo, 0, sizeof(theInfo));
465
466// Calculate the info header size (we round up to 1K)
467//
468 shmInfoSz = (sizeof(ShmInfo)+minInfoSz-1)/minInfoSz*minInfoSz;
469 theInfo.lowFree = theInfo.infoSz = shmInfoSz;
470
471// Calculate the size of each item (rounded to a doubleword)
472//
473 shmItemSz = (shmTypeSz + parms.maxKLen+1 + sizeof(MemItem) + 7)/8*8;
474 theInfo.itemSz = shmItemSz;
475
476// Calculate total amount we need for the items
477//
478 maxEnts = parms.maxKeys;
479 totSz = shmItemSz * maxEnts;
480 totSz = (totSz+7)/8*8;
481
482// Calculate the amount we need for the index
483//
484 indexSz = parms.indexSz*sizeof(int);
485 indexSz = (indexSz+7)/8*8;
486
487// Compute total size and adjust it to be a multiple of the page size
488//
489 totSz = totSz + indexSz + shmInfoSz;
490 totSz = (totSz/PageSize+1)*PageSize;
491
492// Generate the hashID if not specified
493//
494 if (!shmHash) memcpy(&shmHash, "c32 ", sizeof(int));
495
496// Complete the shared memory segment information structure
497//
498 theInfo.index = totSz-indexSz;
499 theInfo.slots = parms.indexSz;
500 theInfo.typeSz = shmTypeSz;
501 theInfo.highUse = theInfo.index;
502 theInfo.reUse = reUse;
503 theInfo.multW = multW;
504 theInfo.keyPos = keyPos = shmTypeSz + sizeof(MemItem);
505 theInfo.maxKeys = maxEnts;
506 theInfo.maxKeySz = maxKLen = parms.maxKLen;
507 theInfo.hashID = shmHash;
508 strncpy(theInfo.typeID, shmType, sizeof(theInfo.typeID)-1);
509 strncpy(theInfo.myName, shmImpl, sizeof(theInfo.myName)-1);
510
511// Create the new filename of the new file we will create
512//
513 n = strlen(shmPath);
514 shmTemp = (char *)malloc(n+8);
515 sprintf(shmTemp, "%s.new", shmPath);
516
517// Open the file creaing as necessary
518//
519 if ((shmFD = ShMam_Open(shmTemp, O_RDWR|O_CREAT, parms.mode)) < 0)
520 return false;
521 accMode = parms.mode;
522 fileHelp.autoClose = true;
523
524// Verify that no one else is using this file.
525//
526 if (!Lock(true, true)) {errno = EADDRINUSE; return false;}
527
528// Make the file as large as need be
529//
530 if (ftruncate(shmFD, 0) || ftruncate(shmFD, totSz)) return false;
531
532// Map the file as a writable shared segment
533//
534 shmBase = (char *)mmap(0, totSz, PROT_READ|PROT_WRITE, MAP_SHARED, shmFD, 0);
535 if (shmBase == MAP_FAILED) return false;
536 shmSize = totSz;
537 isRW = true;
538
539// Copy the segment information into the segment
540//
541 memcpy(shmBase, &theInfo, sizeof(theInfo));
542 xntP.intP = SHMADDR(int, SHMINFO(index)); shmIndex = xntP.antP;
543 shmSlots = parms.indexSz;
544
545// A created table has, by definition, a single writer until it is exported.
546// So, we simply keep the r/w lock on the file until we export the file. Other
547// threads won't change that and other process will not be able to use the file.
548//
549 lockRO = lockRW = false;
550 fileHelp.autoClose = false;
551 return true;
552}
#define ftruncate(a, b)
Definition XrdPosix.hh:65
int maxKeys
Maximum number of keys-value pairs expected in table.
int maxKLen
The maximum acceptable key length.
int mode
Filemode for the newly created file.
int indexSz
Number of four byte hash table entries to create.

References Atomic, ftruncate, XrdSsiShMat::CRZParms::indexSz, XrdSsiShMat::CRZParms::maxKeys, XrdSsiShMat::CRZParms::maxKLen, XrdSsiShMat::CRZParms::mode, XrdSsiShMat::CRZParms::multW, XrdSsiShMat::CRZParms::reUse, SHMADDR, XrdSsiShMat::shmHash, XrdSsiShMat::shmImpl, SHMINFO, XrdSsiShMat::shmPath, XrdSsiShMat::shmType, and XrdSsiShMat::shmTypeSz.

Referenced by Resize().

+ Here is the caller graph for this function:

◆ DelItem()

bool XrdSsiShMam::DelItem ( void *  data,
const char *  key,
int  hash 
)
virtual

Delete an item from the table.

Parameters
dataPointer to the area to receive the value of the deleted key. If the pointer is nil, then the key value is not returned.
keyPointer to the key of length <= MaxKLen.
hashThe hash of the key that is to be used to lookup the key. If the value is zero, an internal hash is computed.
Returns
true - The key and data have been deleted. This is always returned when data is nil.
false - The key and data either not deleted or the key does not exist and data was not nil. The errno value decribes why. Typical reason: the key was not found (errno == ENOENT).

Implements XrdSsiShMat.

Definition at line 558 of file XrdSsiShMam.cc.

559{
560 XLockHelper lockInfo(this, RWLock);
561 MemItem *theItem, *prvItem;
562 int hEnt, iOff;
563
564// Make sure we can delete an item
565//
566 if (!shmSize) {errno = ENOTCONN; return false;}
567 if (!isRW) {errno = EROFS; return false;}
568
569// Check if we need to remap this memory (atomic tests is not needed here)
570//
571 if (verNum != SHMINFO(verNum)) ReMap(RWLock);
572
573// Lock the file if we have multiple writers or recycling items
574// We need to do this prior to file locking as the requirements may change.
575//
576 if (lockRW && !lockInfo.FLock()) return false;
577
578// First try to find the item
579//
580 if (!(hEnt = Find(theItem, prvItem, key, hash)))
581 {if (data) {errno = ENOENT; return false;}
582 return true;
583 }
584
585// Return the contents of the item if the caller wishes that
586//
587 if (data) memcpy(data, ITEM_VAL(theItem), shmTypeSz);
588
589// Delete the item from the index. The update of the count need not be atomic.
590// Also fetching of the next offset need not be atomic as we are the only one.
591//
592 iOff = theItem->next;
593 SHMINFO(itemCount)--;
594 if (prvItem) Atomic_SET_STRICT(prvItem->next, iOff); // Atomic
595 else {if (!iOff) SHMINFO(slotsUsed)--;
596 Atomic_SET_STRICT(shmIndex[hEnt],iOff); // Atomic
597 }
598 RetItem(theItem);
599
600// Indicate the things we updated if need be
601//
602 if (syncOn)
603 {Updated(0);
604 Updated(SHMOFFS(theItem));
605 if (prvItem) Updated(SHMOFFS(prvItem));
606 else Updated(SHMOFFS(&shmIndex[hEnt]));
607 }
608
609// All done
610//
611 return true;
612}

References ITEM_VAL, RWLock, SHMINFO, SHMOFFS, and XrdSsiShMat::shmTypeSz.

◆ Detach()

void XrdSsiShMam::Detach ( )
virtual

Detach the map from the shared memory.

Implements XrdSsiShMat.

Definition at line 618 of file XrdSsiShMam.cc.

619{
620// Clean up
621//
622 if (shmFD >= 0) {close(shmFD); shmFD = -1;}
623 if (shmSize) {munmap(shmBase, shmSize); shmSize = 0;}
624 if (shmTemp) {free(shmTemp); shmTemp = 0;}
625 shmIndex = 0;
626}
#define close(a)
Definition XrdPosix.hh:43

References close.

Referenced by ~XrdSsiShMam().

+ Here is the caller graph for this function:

◆ Enumerate() [1/2]

bool XrdSsiShMam::Enumerate ( void *&  jar)
virtual

Terminate an active enumeration. An active enumeration is any enumeration where the previous form of Enumerate() did not return false. Terminating an active enumeration releases all of the enumeration resources allocated.

Parameters
jarThe opaque cookie initialized by a previous call to Enumerate() requesting the next key-value pair.
Returns
true The enumeration has been terminated and the jar was deleted and the jar pointer is set to zero. Keys are returned in arbitrary order and not all keys may be returned if the map is being actively updated.
false The jar pointer was zero; no enumeration was active.

Implements XrdSsiShMat.

Definition at line 632 of file XrdSsiShMam.cc.

633{
634 EnumJar *theJar = (EnumJar *)jar;
635
636// Close off the enumeration
637//
638 if (theJar) {delete theJar; jar = 0;}
639 return true;
640}

◆ Enumerate() [2/2]

bool XrdSsiShMam::Enumerate ( void *&  jar,
char *&  key,
void *&  val 
)
virtual

Enumerate the keys and assocaited values.

Parameters
jarAn opaque cookie that tracks progress. It should be initialized to zero and otherwise not touched. The same jar must be used for all successive calls. The jar is deleted when false is returned (also see the next Enumerate method).
keyThe pointer variable where the location of the key is returned upon success.
valThe pointer variable where the location f the key values is to be returned upon success.
Returns
true A key and val pointers have been set. Keys are returned in arbitrary order and not all keys may be returned if the map is being actively updated.
false Key not returned; errno holds the reason. Typically, ENOENT there ae no more keys. Other errors may also be reflected. Whne false is returned the jar is deleted and the pointer to it set to zero.

Implements XrdSsiShMat.

Definition at line 644 of file XrdSsiShMam.cc.

645{
646 XLockHelper lockInfo(this, ROLock);
647 EnumJar *theJar = (EnumJar *)jar;
648 MemItem *theItem;
649 long long iTest;
650 int rc, newFD, fence, iOff, hash = 0;
651
652// Make sure we can get an item
653//
654 if (!shmSize) {errno = ENOTCONN; return false;}
655
656// If this is the first call, initialize the jar. First check if we need to
657// remap the segment. We need to do this prior to file locking as the
658// requirements may change. Then create a jar and a shadow copy of the segment.
659//
660 if (!jar)
661 {if (verNum != SHMINFO(verNum)) ReMap(ROLock);
662 if ((newFD = ShMam_Dup(shmFD)) < 0) return false;
663 theJar = new EnumJar(newFD, shmItemSz);
664 jar = theJar;
665 } else if (theJar->iNum < 0)
666 {Enumerate(jar);
667 errno = ENOENT;
668 return false;
669 }
670
671// Lock the file if we have multiple writers or recycling items
672//
673 if (lockRO && !lockInfo.FLock())
674 {rc = errno; Enumerate(jar); errno = rc; return false;}
675
676// Compute the next key we should start the search at but make sure it will not
677// generate an overflow. In the process we fetch the stopping point only once.
678//
679 iTest = (static_cast<long long>(theJar->iNum) * shmItemSz) + shmInfoSz;
680 fence = SHMINFO(lowFree); // Atomic??
681 if (iTest < fence) iOff = static_cast<int>(iTest);
682 else iOff = fence;
683
684// Now start the search. Note that pread() must do a memory fence.
685//
686 theItem = (MemItem *)(theJar->buff);
687 while(iOff < fence)
688 {rc = pread(theJar->fd, theJar->buff, shmItemSz, iOff);
689 if (rc < 0) return false;
690 if (rc != shmItemSz) break;
691 if ((hash = theItem->hash)) break; // Atomic
692 iOff += shmItemSz;
693 }
694
695// Check if we found a key
696//
697 if (!hash) {Enumerate(jar); errno = ENOENT; return false;}
698
699// Return the key and and the associated value
700//
701 key = ITEM_KEY(theItem);
702 val = ITEM_VAL(theItem);
703
704// Compute the contents of the new jar
705//
706 theJar->iNum = (iOff - shmInfoSz)/shmItemSz + 1;
707 return true;
708}
#define pread(a, b, c, d)
Definition XrdPosix.hh:75
bool Enumerate(void *&jar, char *&key, void *&val)

References Enumerate(), ITEM_KEY, ITEM_VAL, pread, ROLock, and SHMINFO.

Referenced by Enumerate().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Export()

bool XrdSsiShMam::Export ( )
virtual

Export a newly created table (i.e. see Create()).

Returns
true - The table has been exported and is now visible to others.
false - The export failed, the errno value describes the reason.

Implements XrdSsiShMat.

Definition at line 714 of file XrdSsiShMam.cc.

715{
716 MutexHelper mtHelp(&myMutex, RWLock);
717
718// Make sure we are attached and in R/W mode and exportable
719//
720 if (!shmSize) {errno = ENOTCONN; return false;}
721 if (!shmTemp) {errno = ENOPROTOOPT; return false;}
722 if (!isRW) {errno = EROFS; return false;}
723
724// All that is left is to export the file using the internal interface. Tell
725// the exporter that we don't have the original file locked.
726//
727 return ExportIt(false);
728}

References RWLock.

◆ GetItem()

bool XrdSsiShMam::GetItem ( void *  data,
const char *  key,
int  hash 
)
virtual

Get an item from the table.

Parameters
dataPointer to an area to receive the value associated with key. If the pointer is nil, then the key value is not returned.
keyPointer to the key of length <= MaxKLen.
hashThe hash of the key that is to be used to lookup the key. If the value is zero, an internal hash is computed.
Returns
true - The key was found and if data was not nil, contains the value associated key.
false - The key not found; errno holds the reason (typically is ENOENT but may be some other reason).

Implements XrdSsiShMat.

Definition at line 854 of file XrdSsiShMam.cc.

855{
856 XLockHelper lockInfo(this, ROLock);
857 MemItem *theItem, *prvItem;
858 int hEnt;
859
860// Make sure we can get an item
861//
862 if (!shmSize) {errno = ENOTCONN; return false;}
863
864// Check if we need to remap this memory (atomic tests is not needed here)
865// We need to do this prior to file locking as the requirements may change.
866//
867 if (verNum != SHMINFO(verNum)) ReMap(ROLock);
868
869// Lock the file if we have multiple writers or recycling items
870//
871 if (lockRO && !lockInfo.FLock()) return false;
872
873// First try to find the item
874//
875 if (!(hEnt = Find(theItem, prvItem, key, hash)))
876 {errno = ENOENT; return false;}
877
878// Return the contents of the item if the caller wishes that
879//
880 if (data) memcpy(data, ITEM_VAL(theItem), shmTypeSz);
881
882// All done
883//
884 return true;
885}

References ITEM_VAL, ROLock, SHMINFO, and XrdSsiShMat::shmTypeSz.

◆ Info()

int XrdSsiShMam::Info ( const char *  vname,
char *  buff = 0,
int  blen = 0 
)
virtual

Return information about the table.

Parameters
vnamePointer to the variable name whose value is wanted. A particular implementation may not support all variable and may support variables not listed here. These are for the default implementation unless otherwise noted. They are: hash - name of hash being used. impl - The table implementation being used. indexsz - Number of index entries indexused - Number of index entries in use keys - Number of keys in the bale. keys/indexused is the hash table collision factor keysfree - Number of keys that can still be added maxkeylen - Longest allowed key multw - If table supports multiple writers, else 0 reuse - If table allows object reuse, else 0 type - Name of the data type in the table. typesz - The number of bytes in the table's data type
buff- Pointer to the buffer to receive text values. Variables that return text are: hash, impl, and type. A buffer must be supplied in any of these variables are requested. If buff is nill or too small a -1 is returned with errno set to EMSGSIZE.
blenThe length of the buffer.
Returns
>=0 - The variable's value or the length of the text information.
< 0 - The variable's value could not be returned; errno has the error code describing the reason, typically ENOTSUP.

Implements XrdSsiShMat.

Definition at line 961 of file XrdSsiShMam.cc.

962{
963 MutexHelper mtHelp(&myMutex, ROLock);
964
965// Make sure we can delete an item
966//
967 if (!shmSize) {errno = ENOTCONN; return 0;}
968
969 if (!strcmp(vname, "atomics"))
970 {int n = strlen(Atomic_IMP);
971 strcpy(buff, Atomic_IMP);
972 return n;
973 }
974
975 if (!strcmp(vname, "hash"))
976 {if (!buff || blen < (int)(sizeof(int)+1)) {errno = EMSGSIZE; return -1;}
977 memcpy(buff, &SHMINFO(hashID), sizeof(int)); buff[sizeof(int)] = 0;
978 return strlen(buff);
979 }
980 if (!strcmp(vname, "impl"))
981 {int n = strlen(SHMINFO(myName));
982 if (!buff || blen < n) {errno = EMSGSIZE; return -1;}
983 strcpy(buff, SHMINFO(myName));
984 return n;
985 }
986 if (!strcmp(vname, "flockro")) return lockRO;
987 if (!strcmp(vname, "flockrw")) return lockRW;
988 if (!strcmp(vname, "indexsz")) return shmSlots;
989 if (!strcmp(vname, "indexused")) return SHMINFO(slotsUsed);
990 if (!strcmp(vname, "keys")) return SHMINFO(itemCount); // Atomic
991 if (!strcmp(vname, "keysfree"))
992 return (SHMINFO(highUse) - SHMINFO(lowFree))/shmItemSz
993 + SHMINFO(freeCount);
994 if (!strcmp(vname, "maxkeylen")) return SHMINFO(maxKeySz);
995 if (!strcmp(vname, "multw")) return multW;
996 if (!strcmp(vname, "reuse")) return reUse;
997 if (!strcmp(vname, "type"))
998 {int n = strlen(SHMINFO(typeID));
999 if (!buff || blen < n) {errno = EMSGSIZE; return -1;}
1000 strcpy(buff, SHMINFO(typeID));
1001 return n;
1002 }
1003 if (!strcmp(vname, "typesz")) return SHMINFO(typeSz);
1004
1005// Return variable not supported
1006//
1007 errno = ENOTSUP;
1008 return -1;
1009}
#define Atomic_IMP

References Atomic_IMP, ROLock, and SHMINFO.

◆ Resize()

bool XrdSsiShMam::Resize ( XrdSsiShMat::CRZParms parms)
virtual

Resize a shared memory segment and associated file specified at object instantiation (see New() method). Resizing is implementation specific but may involve creating a new table and exporting it.

Parameters
parmsResize parameters. See the CRZParms struct for details. For resize, zero values or unspecified flags use the existing table values.
Returns
true - The shared memory was resized, the table can be used.
false - The shared memory could not be resized, errno holds reason.

Implements XrdSsiShMat.

Definition at line 1087 of file XrdSsiShMam.cc.

1088{
1089 XLockHelper lockInfo(this, RWLock);
1090 XrdSsiShMat::NewParms newParms;
1091 MemItem *theItem;
1092 void *val;
1093 char *key;
1094 int fence, iOff, hash;
1095
1096// Make sure we can delete an item
1097//
1098 if (!shmSize) {errno = ENOTCONN; return false;}
1099 if (!isRW) {errno = EROFS; return false;}
1100
1101// Validate parameter list values
1102//
1103 if (parms.indexSz < 0 || parms.maxKeys < 0 || parms.maxKLen < 0)
1104 {errno = EINVAL; return false;}
1105
1106// A resize is not permitted on an un-exported segment
1107//
1108 if (shmTemp) {errno = EPERM; return false;}
1109
1110// Check if we need to remap this memory (atomic tests is not needed here)
1111//
1112 if (verNum != SHMINFO(verNum)) ReMap(RWLock);
1113
1114// Lock the source file
1115//
1116 if (!lockInfo.FLock()) return false;
1117
1118// Setup parms for the segment object
1119//
1120 newParms.impl = shmImpl;
1121 newParms.path = shmPath;
1122 newParms.typeID = shmType;
1123 newParms.typeSz = shmTypeSz;
1124 newParms.hashID = shmHash;
1125
1126// Create a new segment object (this cannot fail).
1127//
1128 XrdSsiShMam newMap(newParms);
1129
1130// Set the values in the parameter list for those wanting the current setting.
1131//
1132 if (!parms.indexSz) parms.indexSz = shmSlots;
1133 if (!parms.maxKeys) parms.maxKeys = SHMINFO(maxKeys);
1134 if (!parms.maxKLen) parms.maxKLen = maxKLen;
1135 if (parms.reUse < 0) parms.reUse = reUse;
1136 if (parms.multW < 0) parms.multW = multW;
1137
1138// Create the new target file
1139//
1140 parms.mode = accMode;
1141 if (!newMap.Create(parms)) return false;
1142
1143// Compute the offset of the first item and get the offset of the last item.
1144//
1145 fence = SHMINFO(lowFree); // Atomic??
1146 iOff = shmInfoSz;
1147
1148// For each item found in the current map add it to the new map
1149//
1150 while(iOff < fence)
1151 {theItem = SHMADDR(MemItem, iOff);
1152 if ((hash = theItem->hash))
1153 {key = ITEM_KEY(theItem);
1154 val = ITEM_VAL(theItem);
1155 if (!newMap.AddItem(val, 0, key, hash, true)) return false;
1156 }
1157 iOff += shmItemSz;
1158 }
1159
1160// We need to drop the lock on the file otherwise the export will hang
1161//
1162
1163// All went well, so export this the new map using the internal interface as
1164// we already have the source file locked and export normally tries to lock it.
1165//
1166 if (!newMap.ExportIt(true)) return false;
1167
1168// All that we need to do is to swap the map with our map and we are done.
1169//
1170 SwapMap(newMap);
1171 return true;
1172}
const char * typeID
The name of the type associated with the key.
const char * impl
Implementation name.
const char * path
The path to the backing file for the table.
int hashID
The hash being used (0 means the default)
int typeSz
Size of the type in bytes.

References AddItem(), Create(), XrdSsiShMat::NewParms::hashID, XrdSsiShMat::NewParms::impl, XrdSsiShMat::CRZParms::indexSz, ITEM_KEY, ITEM_VAL, XrdSsiShMat::CRZParms::maxKeys, XrdSsiShMat::CRZParms::maxKLen, XrdSsiShMat::CRZParms::mode, XrdSsiShMat::CRZParms::multW, XrdSsiShMat::NewParms::path, XrdSsiShMat::CRZParms::reUse, RWLock, SHMADDR, XrdSsiShMat::shmHash, XrdSsiShMat::shmImpl, SHMINFO, XrdSsiShMat::shmPath, XrdSsiShMat::shmType, XrdSsiShMat::shmTypeSz, XrdSsiShMat::NewParms::typeID, and XrdSsiShMat::NewParms::typeSz.

+ Here is the call graph for this function:

◆ Sync() [1/3]

bool XrdSsiShMam::Sync ( )
virtual

Synchronize all modified pages to the associated backing file.

Returns
true - Operation completed successfully.
false - Operation failed; errno holds the error code explaining why.

Implements XrdSsiShMat.

Definition at line 1274 of file XrdSsiShMam.cc.

1275{
1276 MutexHelper mtHelp(&myMutex, RWLock);
1277
1278// Make sure we are attached and in R/W mode
1279//
1280 if (!shmSize) {errno = ENOTCONN; return false;}
1281 if (!isRW) {errno = EROFS; return false;}
1282
1283// For now do a flush as this works in Linux. We may need to generalize this
1284// for all platforms using msync, sigh.
1285//
1286 if (!Flush()) return false;
1287
1288// Reset counters
1289//
1290 syncBase = false;
1291 syncLast = 0;
1292 syncQWR = 0;
1293 return true;
1294}

References RWLock.

◆ Sync() [2/3]

bool XrdSsiShMam::Sync ( bool  dosync,
bool  syncdo 
)
virtual

Turn memry synchronization on or off.

Parameters
dosyncWhen true, modified table pages are written back to the backing file. The synchronous or async nature of the write is controlled by the second parameter. When false, memory-file synchronization is turned off (initial setting).
syncdoWhen true, synchronization is done in the forground. That is, a call triggering a sync will not return until complete. When false, synchronization is done in the background.
Returns
true - Operation completed successfully.
false - Operation failed; errno holds the error code explaining why.

Implements XrdSsiShMat.

Definition at line 1320 of file XrdSsiShMam.cc.

1321{
1322 MutexHelper mtHelp(&myMutex, RWLock);
1323
1324// Make sure we are attached and in R/W mode
1325//
1326 if (!shmSize) {errno = ENOTCONN; return false;}
1327 if (!isRW) {errno = EROFS; return false;}
1328
1329// Flush out pages if sync it turned on
1330//
1331 if (syncOn && !Flush()) return false;
1332
1333// Set new options
1334//
1335 syncOn = dosync;
1336 syncOpt = (syncdo ? MS_SYNC : MS_ASYNC);
1337 return true;
1338}

References RWLock.

◆ Sync() [3/3]

bool XrdSsiShMam::Sync ( int  synqsz)
virtual

Set the sync defer queue size.

Parameters
synqszThe maximum number of modified pages before flushing.
Returns
true - Operation completed successfully.
false - Operation failed; errno holds the error code explaining why.

Implements XrdSsiShMat.

Definition at line 1298 of file XrdSsiShMam.cc.

1299{
1300 MutexHelper mtHelp(&myMutex, RWLock);
1301
1302// Make sure we are attached and in R/W mode
1303//
1304 if (!shmSize) {errno = ENOTCONN; return false;}
1305 if (!isRW) {errno = EROFS; return false;}
1306 if (syncqsz < 0) {errno = EINVAL; return false;}
1307
1308// Flush out pages if sync it turned on
1309//
1310 if (syncOn && !Flush()) return false;
1311
1312// Set new queue size
1313//
1314 syncQSZ = syncqsz;
1315 return true;
1316}

References RWLock.


The documentation for this class was generated from the following files: