procsm.cpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. #include <iostream>
  2. #include <thread>
  3. #include <QTime>
  4. #include <QThread>
  5. #include "procsm.h"
  6. class AttachThread : public QThread
  7. {
  8. public:
  9. AttachThread(QSharedMemory * pa,bool & bAttach)
  10. {
  11. mbAttach = bAttach;
  12. mpa = pa;
  13. mbrun = true;
  14. }
  15. QSharedMemory * mpa;
  16. bool mbAttach = false;
  17. bool mbrun = true;
  18. void run()
  19. {
  20. mbAttach = mpa->attach();
  21. mbrun = false;
  22. }
  23. };
  24. procsm::procsm(const char * strsmname,const unsigned int nBufSize,const unsigned int nMaxPacCount,const int nMode)
  25. {
  26. // mnBufSize = nBufSize;
  27. // qDebug("create dbus");
  28. mpASM = new QSharedMemory(strsmname);
  29. if(nMode == ModeWrite)
  30. {
  31. mmodulemsg_type.mnBufSize = nBufSize;
  32. mmodulemsg_type.mnMsgBufCount = nMaxPacCount;
  33. strncpy(mmodulemsg_type.mstrmsgname,strsmname,255);
  34. #ifdef USEDBUS
  35. mmsg = QDBusMessage::createSignal("/catarc/adc", "adc.adciv.modulecomm", strsmname);
  36. mmsg<<1;
  37. #endif
  38. bool bAttach = false;
  39. AttachThread AT(mpASM,bAttach);
  40. AT.start();
  41. QTime xTime;
  42. xTime.start();
  43. while(xTime.elapsed()<100)
  44. {
  45. if(AT.mbrun == false)
  46. {
  47. bAttach = AT.mbAttach;
  48. break;
  49. }
  50. }
  51. // qDebug("time is %d",xTime.elapsed());
  52. if(xTime.elapsed()>= 1000)
  53. {
  54. qDebug("in 1000ms Attach fail.terminate it .");
  55. AT.terminate();
  56. bAttach = false;
  57. }
  58. // if(!mpASM->attach())
  59. if(!bAttach)
  60. {
  61. mpASM->create(sizeof(procsm_info)+nMaxPacCount*sizeof(procsm_head) + nBufSize);
  62. char * p = (char *)mpASM->data();
  63. mpinfo = (procsm_info *)p;
  64. mphead = (procsm_head *)(p+sizeof(procsm_info));
  65. mpinfo->mCap = nMaxPacCount;
  66. mpinfo->mnBufSize = nBufSize;
  67. mpinfo->mFirst = 0;
  68. mpinfo->mNext = 0;
  69. mpinfo->mLock = 0;
  70. }
  71. if(mpASM->isAttached())
  72. {
  73. mbAttach = true;
  74. char * p = (char *)mpASM->data();
  75. mpinfo = (procsm_info *)p;
  76. mphead = (procsm_head *)(p+sizeof(procsm_info));
  77. mnMaxPacCount = mpinfo->mCap;
  78. mnBufSize = mpinfo->mnBufSize;
  79. // qDebug("attach successful");
  80. mstrtem = new char[mnBufSize];
  81. #ifdef USEDBUS
  82. mmsgres = QDBusMessage::createSignal("/catarc/adc", "adciv.interface", "modulemsgres");
  83. mmsgres<<1;
  84. bool bconnect = QDBusConnection::sessionBus().connect(QString(),"/catarc/adc", "adciv.interface", "modulemsgquery",this,SLOT(onQuery()));
  85. if(bconnect == false)
  86. {
  87. std::cout<<"procsm_if_readthread::procsm_if_readthread bconect is false"<<std::endl;
  88. }
  89. #endif
  90. }
  91. else
  92. {
  93. mbAttach = false;
  94. qDebug("Share Memory Error.");
  95. }
  96. }
  97. }
  98. #ifdef USEDBUS
  99. void procsm::onQuery()
  100. {
  101. QByteArray ba;
  102. ba.append((char *)&mmodulemsg_type,sizeof(iv::modulemsg_type));
  103. QList<QVariant> x;
  104. x<<ba;
  105. mmsgres.setArguments(x);
  106. QDBusConnection::sessionBus().send(mmsgres);
  107. }
  108. #endif
  109. bool procsm::AttachMem()
  110. {
  111. mpASM->attach();
  112. if(mpASM->isAttached())
  113. {
  114. mbAttach = true;
  115. char * p = (char *)mpASM->data();
  116. mpinfo = (procsm_info *)p;
  117. mphead = (procsm_head *)(p+sizeof(procsm_info));
  118. mnMaxPacCount = mpinfo->mCap;
  119. mnBufSize = mpinfo->mnBufSize;
  120. return true;
  121. }
  122. else
  123. {
  124. return false;
  125. }
  126. }
  127. int procsm::MoveMem(const unsigned int nSize)
  128. {
  129. // qDebug("move mem");
  130. unsigned int nRemove = nSize;
  131. if(nRemove == 0)return -1;
  132. // unsigned int * pIndexFirst = (unsigned int *)mpASM->data();
  133. // unsigned int * pIndexNext = pIndexFirst+1;
  134. // qDebug("first = %d next = %d",*pIndexFirst,*pIndexNext);
  135. // unsigned int * pIndexNext = pIndexFirst;
  136. char * pH,*pD;
  137. pH = (char *)mpASM->data();pH = pH + sizeof(procsm_info);
  138. pD = (char *)mpASM->data();pD = pD + sizeof(procsm_info) + mnMaxPacCount * sizeof(procsm_head);
  139. procsm_head * phh = (procsm_head *)pH;
  140. unsigned int nPac = mpinfo->mNext - mpinfo->mFirst;
  141. if(nRemove >nPac)
  142. {
  143. // qDebug("procsm::MoveMem nRemove > nPac nRemove = %d",nRemove);
  144. nRemove = nPac;
  145. }
  146. if(nRemove == nPac)
  147. {
  148. mpinfo->mFirst = mpinfo->mFirst + (unsigned int)nRemove;
  149. return 0;
  150. }
  151. unsigned int i;
  152. int nDataMove = 0;
  153. for(i=0;i<nRemove;i++)
  154. {
  155. procsm_head * phd = phh+i;
  156. nDataMove = nDataMove + phd->mnLen;
  157. }
  158. unsigned int nDataTotal;
  159. for(i=0;i<(nPac - nRemove);i++)
  160. {
  161. memcpy(phh+i,phh+i+nRemove,sizeof(procsm_head));
  162. (phh+i)->mnPos = (phh+i)->mnPos - nDataMove;
  163. }
  164. nDataTotal = (phh + nPac-nRemove-1)->mnPos + (phh+nPac-nRemove-1)->mnLen;
  165. memcpy(mstrtem,pD+nDataMove,nDataTotal);
  166. memcpy(pD,mstrtem,nDataTotal);
  167. // for(i=0;i<nDataTotal;i++)
  168. // {
  169. // *(pD+i) = *(pD+i+nDataMove);
  170. // }
  171. mpinfo->mFirst = mpinfo->mFirst + (unsigned int)nRemove;
  172. return 0;
  173. }
  174. int procsm::writemsg(const char *str, const unsigned int nSize)
  175. {
  176. if(nSize > mnBufSize)
  177. {
  178. qDebug("procsm::writemsg message size is very big");
  179. return -1;
  180. }
  181. if(mbAttach == false)
  182. {
  183. std::cout<<"ShareMemory Attach fail."<<std::endl;
  184. return -1;
  185. }
  186. mpASM->lock();
  187. // unsigned int * pIndexFirst = (unsigned int *)mpASM->data();
  188. // unsigned int * pIndexNext = pIndexFirst+1;
  189. if(mpinfo->mLock == 1)
  190. {
  191. std::cout<<"ShareMemory have lock.Init."<<std::endl;
  192. mpinfo->mLock = 0;
  193. mpinfo->mFirst = 0;
  194. mpinfo->mNext = 0;
  195. }
  196. mpinfo->mLock =1;
  197. WRITEMSG:
  198. char * pH,*pD;
  199. QDateTime dt;
  200. pH = (char *)mpASM->data();pH = pH + sizeof(procsm_info);
  201. pD = (char *)mpASM->data();pD = pD + sizeof(procsm_info) + mnMaxPacCount * sizeof(procsm_head);
  202. procsm_head * phh = (procsm_head *)pH;
  203. unsigned int nPac = mpinfo->mNext - mpinfo->mFirst;
  204. if(nPac>=mnMaxPacCount)
  205. {
  206. unsigned int nRemove = mnMaxPacCount/3;
  207. if(nRemove == 0)nRemove = 1;
  208. MoveMem(nRemove);
  209. goto WRITEMSG;
  210. }
  211. if(nPac == 0)
  212. {
  213. memcpy(pD,str,nSize);
  214. dt = QDateTime::currentDateTime();
  215. // phh->mdt = dt;
  216. phh->SetDate(dt);
  217. // memcpy(&phh->mdt,&dt,sizeof(QDateTime));
  218. // phh->mdt = QDateTime::currentDateTime();
  219. phh->mindex = mpinfo->mNext;
  220. phh->mnPos = 0;
  221. phh->mnLen = nSize;
  222. mpinfo->mNext = mpinfo->mNext+1;
  223. }
  224. else
  225. {
  226. if(((phh+nPac-1)->mnPos+(phh+nPac-1)->mnLen + nSize)>=mnBufSize)
  227. {
  228. unsigned int nRemove = mnMaxPacCount/2;
  229. if(nRemove == 0)nRemove = 1;
  230. MoveMem(nRemove);
  231. goto WRITEMSG;
  232. }
  233. else
  234. {
  235. unsigned int nPos = (phh+nPac-1)->mnPos + (phh+nPac-1)->mnLen;
  236. // qDebug("write pos = %d",nPos);
  237. memcpy(pD+nPos,str,nSize);
  238. dt = QDateTime::currentDateTime();
  239. (phh+nPac)->SetDate(dt);
  240. // memcpy(&(phh+nPac)->mdt,&dt,sizeof(QDateTime));
  241. // (phh+nPac)->mdt = QDateTime::currentDateTime();
  242. (phh+nPac)->mindex = mpinfo->mNext;
  243. (phh+nPac)->mnPos = nPos;
  244. (phh+nPac)->mnLen = nSize;
  245. mpinfo->mNext = mpinfo->mNext+1;
  246. }
  247. }
  248. const unsigned int nTM = 0x6fffffff;
  249. if((mpinfo->mNext >nTM)&&(mpinfo->mFirst>nTM))
  250. {
  251. nPac = mpinfo->mNext - mpinfo->mFirst;
  252. unsigned int i;
  253. for(i=0;i<nPac;i++)
  254. {
  255. (phh+i)->mindex = (phh+i)->mindex-nTM;
  256. }
  257. mpinfo->mFirst = mpinfo->mFirst-nTM;
  258. mpinfo->mNext = mpinfo->mNext - nTM;
  259. }
  260. mpinfo->mLock = 0;
  261. mpASM->unlock();
  262. #ifdef USEDBUS
  263. QDBusConnection::sessionBus().send(mmsg);
  264. #endif
  265. return 0;
  266. }
  267. unsigned int procsm::getcurrentnext()
  268. {
  269. unsigned int nNext;
  270. mpASM->lock();
  271. nNext = mpinfo->mNext;
  272. mpASM->unlock();
  273. return nNext;
  274. }
  275. //if return 0 No Data.
  276. //if return -1 nMaxSize is small
  277. //if retrun -2 index is not in range,call getcurrentnext get position
  278. //if return > 0 readdata
  279. int procsm::readmsg(unsigned int index, char *str, unsigned int nMaxSize,unsigned int * nRead,QDateTime * pdt)
  280. {
  281. if(mbAttach == false)
  282. {
  283. std::cout<<"ShareMemory Attach fail."<<std::endl;
  284. return -1;
  285. }
  286. int nRtn = 0;
  287. mpASM->lock();
  288. if((index< mpinfo->mFirst)||(index > mpinfo->mNext))
  289. {
  290. nRtn = -2;
  291. }
  292. if(nRtn != (-2))
  293. {
  294. if(index == mpinfo->mNext)
  295. {
  296. nRtn = 0;
  297. }
  298. else
  299. {
  300. char * pH,*pD;
  301. // pH = (char *)mpASM->data();pH = pH + 2*sizeof(unsigned int);
  302. // pD = (char *)mpASM->data();pD = pD + 2*sizeof(unsigned int) + mnMaxPacCount * sizeof(procsm_head);
  303. pD = (char *)mpASM->data();pD = pD+ sizeof(procsm_info) + mpinfo->mCap*sizeof(procsm_head);
  304. pH = (char *)mpASM->data();pH = pH+sizeof(procsm_info);
  305. procsm_head * phh = (procsm_head *)pH;
  306. unsigned int nPac = mpinfo->mNext - mpinfo->mFirst;
  307. if(nPac == 0)
  308. {
  309. nRtn = 0;
  310. }
  311. else
  312. {
  313. unsigned int nPos = index - mpinfo->mFirst;
  314. *nRead = (phh+nPos)->mnLen;
  315. if((phh+nPos)->mnLen > nMaxSize)
  316. {
  317. nRtn = -1;
  318. }
  319. else
  320. {
  321. // qDebug("read pos = %d",(phh+nPos)->mnPos);
  322. memcpy(str,pD + (phh+nPos)->mnPos,(phh+nPos)->mnLen);
  323. // qDebug("read pos = %d",(phh+nPos)->mnPos);
  324. nRtn = (phh+nPos)->mnLen;
  325. (phh+nPos)->GetDate(pdt);
  326. // memcpy(pdt,&((phh+nPos)->mdt),sizeof(QDateTime));
  327. }
  328. }
  329. }
  330. }
  331. mpASM->unlock();
  332. return nRtn;
  333. }