Belle II Software development
NSMDataStore.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include "daq/slc/nsm/NSMDataStore.h"
9
10#include <daq/slc/system/Time.h>
11
12#include <daq/slc/base/StringUtil.h>
13
14#include <cstdio>
15#include <cstring>
16#include <sys/mman.h>
17#include <netinet/in.h>
18#include <arpa/inet.h>
19#include <daq/slc/system/LockGuard.h>
20
21using namespace Belle2;
22
23NSMDataStore NSMDataStore::g_store;
24
25bool NSMDataStore::open(unsigned short max)
26{
27 size_t size = (max > 0) ? m_mutex.size() + m_cond.size() +
28 sizeof(Header) + sizeof(Entry) * max : 0;
29 if (!m_mem.open("NSMDataStore", size)) {
30 return false;
31 }
32 m_mem.truncate(0);
33 char* buf = (char*)m_mem.map();
34 m_buf = buf;
35 m_mutex = MMutex(buf);
36 buf += m_mutex.size();
37 m_cond = MCond(buf);
38 buf += m_cond.size();
39 m_header = reinterpret_cast<Header*>(buf);
40 buf += sizeof(Header);
41 m_entries = reinterpret_cast<Entry*>(buf);
42 if (max > 0) {
43 m_header->maxentries = max;
44 }
45 return true;
46}
47
48void NSMDataStore::init()
49{
50 if (m_header == NULL) return;
51 int max = m_header->maxentries;
52 memset(m_buf, 0, m_mem.size());
53 m_header->maxentries = max;
54 m_mutex.init();
55 m_cond.init();
56}
57
58NSMDataStore::Entry* NSMDataStore::add(unsigned int addr,
59 unsigned int size,
60 unsigned int revision,
61 const std::string& name,
62 const std::string& format,
63 unsigned int rid)
64{
65 MLockGuard lockGuard(m_mutex);
66 unsigned int n = m_header->nentries;
67 for (unsigned int i = 0; i < n; i++) {
68 if (m_entries[i].id > 0 && name == m_entries[i].name) {
69 return &m_entries[i];
70 }
71 }
72 memset(&m_entries[n], 0, sizeof(Entry));
73 m_entries[n].id = n + 1;
74 m_entries[n].rid = rid;
75 m_entries[n].addr = addr;
76 m_entries[n].size = size;
77 m_entries[n].revision = revision;
78 m_entries[n].utime = (unsigned int)Time().getSecond();
79 strcpy(m_entries[n].name, name.c_str());
80 strcpy(m_entries[n].format, format.c_str());
81 m_header->nentries++;
82 return &m_entries[n];
83}
84
85NSMDataStore::Entry* NSMDataStore::get(const std::string& name)
86{
87 MLockGuard lockGuard(m_mutex);
88 const unsigned int n = m_header->nentries;
89 for (unsigned int i = 0; i < n; i++) {
90 if (m_entries[i].id > 0 && name == m_entries[i].name) {
91 return &m_entries[i];
92 }
93 }
94 return NULL;
95}
96
97NSMDataStore::Entry* NSMDataStore::get(unsigned int id)
98{
99 if (id == 0) return NULL;
100 MLockGuard lockGuard(m_mutex);
101 const unsigned int n = m_header->nentries;
102 for (unsigned int i = 0; i < n; i++) {
103 if (m_entries[i].id > 0 &&
104 m_entries[i].id == (unsigned int)id) {
105 return &m_entries[i];
106 }
107 }
108 return NULL;
109}
110
111NSMDataStore::Entry* NSMDataStore::get(unsigned int addr,
112 unsigned int id)
113{
114 if (id == 0) return NULL;
115 MLockGuard lockGuard(m_mutex);
116 const unsigned int n = m_header->nentries;
117 for (unsigned int i = 0; i < n; i++) {
118 if (m_entries[i].rid > 0 &&
119 m_entries[i].addr == (unsigned int)addr &&
120 m_entries[i].rid == (unsigned int)id) {
121 return &m_entries[i];
122 }
123 }
124 return NULL;
125}
126
127void NSMDataStore::unlink()
128{
129 const unsigned int n = m_header->nentries;
130 for (unsigned int i = 0; i < n; i++) {
131 char* name = m_entries[i].name;
132 if (strlen(name) > 0) {
133 std::string path = "";
134 sockaddr_in sa;
135 sa.sin_addr.s_addr = m_entries[i].addr;
136 if (m_entries[i].addr > 0) {
137 path = StringUtil::form("%s:%s",
138 inet_ntoa(sa.sin_addr), name);
139 } else {
140 path = StringUtil::form("127.0.0.1:%s", name);
141 }
142 shm_unlink(path.c_str());
143 }
144 }
145 m_mem.unlink();
146}
Lock Guard for a Mutex instance.
Definition: LockGuard.h:47
Abstract base class for different kinds of events.