elog_file_port.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * This file is part of the EasyLogger Library.
  3. *
  4. * Copyright (c) 2015-2019, Qintl, <qintl_linux@163.com>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining
  7. * a copy of this software and associated documentation files (the
  8. * 'Software'), to deal in the Software without restriction, including
  9. * without limitation the rights to use, copy, modify, merge, publish,
  10. * distribute, sublicense, and/or sell copies of the Software, and to
  11. * permit persons to whom the Software is furnished to do so, subject to
  12. * the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be
  15. * included in all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
  18. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  21. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. *
  25. * Function: Portable interface for EasyLogger's file log pulgin.
  26. * Created on: 2019-01-05
  27. */
  28. #include <stdio.h>
  29. #include <sys/types.h>
  30. #include <sys/stat.h>
  31. #include <fcntl.h>
  32. #include <sys/ipc.h>
  33. #include <sys/sem.h>
  34. #include <unistd.h>
  35. #include <elog_file.h>
  36. #include <elog_file_cfg.h>
  37. #define ELOG_FILE_SEM_KEY ((key_t)0x19910612)
  38. #ifdef _SEM_SEMUN_UNDEFINED
  39. union semun {
  40. int val; /* Value for SETVAL */
  41. struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
  42. unsigned short *array; /* Array for GETALL, SETALL */
  43. struct seminfo *__buf; /* Buffer for IPC_INFO
  44. (Linux-specific) */
  45. };
  46. #endif
  47. static int semid = -1;
  48. static struct sembuf const up = {0, 1, SEM_UNDO};
  49. static struct sembuf const down = {0, -1, SEM_UNDO};
  50. static void lock_init(void);
  51. static int lock_open(void);
  52. static void lock_deinit(void);
  53. /**
  54. * EasyLogger flile log pulgin port initialize
  55. *
  56. * @return result
  57. */
  58. int elog_file_port_init(void) {
  59. int result = 0;
  60. lock_init();
  61. return result;
  62. }
  63. /**
  64. * file log lock
  65. */
  66. inline void elog_file_port_lock(void)
  67. {
  68. semid == -1 ? -1 : semop(semid, (struct sembuf *)&down, 1);
  69. }
  70. /**
  71. * file log unlock
  72. */
  73. inline void elog_file_port_unlock(void)
  74. {
  75. semid == -1 ? -1 : semop(semid, (struct sembuf *)&up, 1);
  76. }
  77. /**
  78. * file log deinit
  79. */
  80. void elog_file_port_deinit(void)
  81. {
  82. lock_deinit();
  83. }
  84. /**
  85. * initialize the lock
  86. */
  87. static void lock_init(void)
  88. {
  89. int id, rc;
  90. union semun arg;
  91. struct sembuf sembuf;
  92. id = semget(ELOG_FILE_SEM_KEY, 1, IPC_CREAT | IPC_EXCL | 0666);
  93. if(likely(id == -1)) {
  94. id = lock_open();
  95. if (id == -1)
  96. goto __exit;
  97. } else {
  98. arg.val = 0;
  99. rc = semctl(id, 0, SETVAL, arg);
  100. if (rc == -1)
  101. goto __exit;
  102. sembuf.sem_num = 0;
  103. sembuf.sem_op = 1;
  104. sembuf.sem_flg = 0;
  105. rc = semop(id, &sembuf, 1);
  106. if (rc == -1)
  107. goto __exit;
  108. }
  109. semid = id;
  110. __exit:
  111. return ;
  112. }
  113. /**
  114. * gets the lock
  115. */
  116. static int lock_open(void)
  117. {
  118. int id, rc, i;
  119. union semun arg;
  120. struct semid_ds ds;
  121. id = semget(ELOG_FILE_SEM_KEY, 1, 0666);
  122. if(unlikely(id == -1))
  123. goto err;
  124. arg.buf = &ds;
  125. for (i = 0; i < 10; i++) {
  126. rc = semctl(id, 0, IPC_STAT, arg);
  127. if (unlikely(rc == -1))
  128. goto err;
  129. if(ds.sem_otime != 0)
  130. break;
  131. usleep(10 * 1000);
  132. }
  133. if (unlikely(ds.sem_otime == 0))
  134. goto err;
  135. return id;
  136. err:
  137. return -1;
  138. }
  139. /**
  140. * deinitialize the lock
  141. */
  142. static void lock_deinit(void)
  143. {
  144. semid = -1;
  145. }