/[LeafOK_CVS]/lbbs/src/user_list.c
ViewVC logotype

Diff of /lbbs/src/user_list.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.41 by sysadm, Thu Nov 20 03:22:35 2025 UTC Revision 1.43 by sysadm, Thu Nov 20 10:20:51 2025 UTC
# Line 23  Line 23 
23  #include <time.h>  #include <time.h>
24  #include <sys/mman.h>  #include <sys/mman.h>
25  #include <sys/param.h>  #include <sys/param.h>
 #include <sys/sem.h>  
26  #include <sys/stat.h>  #include <sys/stat.h>
27    
28  #if defined(_SEM_SEMUN_UNDEFINED) || defined(__CYGWIN__)  #ifdef HAVE_SYSTEM_V
29    #include <sys/sem.h>
30    
31    #ifdef _SEM_SEMUN_UNDEFINED
32  union semun  union semun
33  {  {
34          int val;                           /* Value for SETVAL */          int val;                           /* Value for SETVAL */
35          struct semid_ds *buf;  /* Buffer for IPC_STAT, IPC_SET */          struct semid_ds *buf;  /* Buffer for IPC_STAT, IPC_SET */
36          unsigned short *array; /* Array for GETALL, SETALL */          unsigned short *array; /* Array for GETALL, SETALL */
37          struct seminfo *__buf; /* Buffer for IPC_INFO          struct seminfo *__buf; /* Buffer for IPC_INFO
38                                                            (Linux-specific) */                                                          (Linux-specific) */
39  };  };
40  #endif // #if defined(_SEM_SEMUN_UNDEFINED)  #endif // #ifdef _SEM_SEMUN_UNDEFINED
41    
42    #else
43    #include <semaphore.h>
44    #endif
45    
46  enum _user_list_constant_t  enum _user_list_constant_t
47  {  {
# Line 46  enum _user_list_constant_t Line 52  enum _user_list_constant_t
52  struct user_list_pool_t  struct user_list_pool_t
53  {  {
54          size_t shm_size;          size_t shm_size;
55    #ifndef HAVE_SYSTEM_V
56            sem_t sem;
57            uint16_t read_lock_count;
58            uint16_t write_lock_count;
59    #else
60          int semid;          int semid;
61    #endif
62          USER_LIST user_list[2];          USER_LIST user_list[2];
63          int user_list_index_current;          int user_list_index_current;
64          int user_list_index_new;          int user_list_index_new;
# Line 393  int user_list_pool_init(const char *file Line 405  int user_list_pool_init(const char *file
405          int fd;          int fd;
406          size_t size;          size_t size;
407          void *p_shm;          void *p_shm;
408    #ifdef HAVE_SYSTEM_V
409          int proj_id;          int proj_id;
410          key_t key;          key_t key;
411          int semid;          int semid;
412          union semun arg;          union semun arg;
413    #endif
414          int i;          int i;
415    
416          if (p_user_list_pool != NULL || p_trie_action_dict != NULL)          if (p_user_list_pool != NULL || p_trie_action_dict != NULL)
# Line 463  int user_list_pool_init(const char *file Line 477  int user_list_pool_init(const char *file
477          p_user_list_pool->shm_size = size;          p_user_list_pool->shm_size = size;
478    
479          // Allocate semaphore as user list pool lock          // Allocate semaphore as user list pool lock
480    #ifndef HAVE_SYSTEM_V
481            if (sem_init(&(p_user_list_pool->sem), 1, 1) == -1)
482            {
483                    log_error("sem_init() error (%d)\n", errno);
484                    return -3;
485            }
486    
487            p_user_list_pool->read_lock_count = 0;
488            p_user_list_pool->write_lock_count = 0;
489    #else
490          proj_id = (int)(time(NULL) % getpid());          proj_id = (int)(time(NULL) % getpid());
491          key = ftok(filename, proj_id);          key = ftok(filename, proj_id);
492          if (key == -1)          if (key == -1)
# Line 491  int user_list_pool_init(const char *file Line 515  int user_list_pool_init(const char *file
515          }          }
516    
517          p_user_list_pool->semid = semid;          p_user_list_pool->semid = semid;
518    #endif
519    
520          // Set user counts to 0          // Set user counts to 0
521          p_user_list_pool->user_list[0].user_count = 0;          p_user_list_pool->user_list[0].user_count = 0;
# Line 514  void user_list_pool_cleanup(void) Line 539  void user_list_pool_cleanup(void)
539                  return;                  return;
540          }          }
541    
542    #ifdef HAVE_SYSTEM_V
543          if (semctl(p_user_list_pool->semid, 0, IPC_RMID) == -1)          if (semctl(p_user_list_pool->semid, 0, IPC_RMID) == -1)
544          {          {
545                  log_error("semctl(semid = %d, IPC_RMID) error (%d)\n", p_user_list_pool->semid, errno);                  log_error("semctl(semid = %d, IPC_RMID) error (%d)\n", p_user_list_pool->semid, errno);
546          }          }
547    #else
548            if (sem_destroy(&(p_user_list_pool->sem)) == -1)
549            {
550                    log_error("sem_destroy() error (%d)\n", errno);
551            }
552    #endif
553    
554          detach_user_list_pool_shm();          detach_user_list_pool_shm();
555    
# Line 645  cleanup: Line 677  cleanup:
677    
678  int user_list_try_rd_lock(int wait_sec)  int user_list_try_rd_lock(int wait_sec)
679  {  {
680    #ifdef HAVE_SYSTEM_V
681          struct sembuf sops[2];          struct sembuf sops[2];
 #ifndef __CYGWIN__  
         struct timespec timeout;  
682  #endif  #endif
683          int ret;          struct timespec timeout;
684            int ret = 0;
685    
686          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
687          {          {
# Line 657  int user_list_try_rd_lock(int wait_sec) Line 689  int user_list_try_rd_lock(int wait_sec)
689                  return -1;                  return -1;
690          }          }
691    
692            timeout.tv_sec = wait_sec;
693            timeout.tv_nsec = 0;
694    
695    #ifdef HAVE_SYSTEM_V
696          sops[0].sem_num = 1; // w_sem          sops[0].sem_num = 1; // w_sem
697          sops[0].sem_op = 0;      // wait until unlocked          sops[0].sem_op = 0;      // wait until unlocked
698          sops[0].sem_flg = 0;          sops[0].sem_flg = 0;
# Line 665  int user_list_try_rd_lock(int wait_sec) Line 701  int user_list_try_rd_lock(int wait_sec)
701          sops[1].sem_op = 1;                     // lock          sops[1].sem_op = 1;                     // lock
702          sops[1].sem_flg = SEM_UNDO; // undo on terminate          sops[1].sem_flg = SEM_UNDO; // undo on terminate
703    
 #ifdef __CYGWIN__  
         ret = semop(p_user_list_pool->semid, sops, 2);  
 #else  
         timeout.tv_sec = wait_sec;  
         timeout.tv_nsec = 0;  
   
704          ret = semtimedop(p_user_list_pool->semid, sops, 2, &timeout);          ret = semtimedop(p_user_list_pool->semid, sops, 2, &timeout);
 #endif  
705          if (ret == -1 && errno != EAGAIN && errno != EINTR)          if (ret == -1 && errno != EAGAIN && errno != EINTR)
706          {          {
707                  log_error("semop(lock read) error %d\n", errno);                  log_error("semop(lock read) error %d\n", errno);
708          }          }
709    #else
710            if (sem_timedwait(&(p_user_list_pool->sem), &timeout) == -1)
711            {
712                    if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)
713                    {
714                            log_error("sem_timedwait() error %d\n", errno);
715                    }
716                    return -1;
717            }
718    
719            if (p_user_list_pool->write_lock_count == 0)
720            {
721                    p_user_list_pool->read_lock_count++;
722            }
723            else
724            {
725                    errno = EAGAIN;
726                    ret = -1;
727            }
728    
729            if (sem_post(&(p_user_list_pool->sem)) == -1)
730            {
731                    log_error("sem_post() error %d\n", errno);
732                    return -1;
733            }
734    #endif
735    
736          return ret;          return ret;
737  }  }
738    
739  int user_list_try_rw_lock(int wait_sec)  int user_list_try_rw_lock(int wait_sec)
740  {  {
741    #ifdef HAVE_SYSTEM_V
742          struct sembuf sops[3];          struct sembuf sops[3];
 #ifndef __CYGWIN__  
         struct timespec timeout;  
743  #endif  #endif
744          int ret;          struct timespec timeout;
745            int ret = 0;
746    
747          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
748          {          {
# Line 695  int user_list_try_rw_lock(int wait_sec) Line 750  int user_list_try_rw_lock(int wait_sec)
750                  return -1;                  return -1;
751          }          }
752    
753            timeout.tv_sec = wait_sec;
754            timeout.tv_nsec = 0;
755    
756    #ifdef HAVE_SYSTEM_V
757          sops[0].sem_num = 1; // w_sem          sops[0].sem_num = 1; // w_sem
758          sops[0].sem_op = 0;      // wait until unlocked          sops[0].sem_op = 0;      // wait until unlocked
759          sops[0].sem_flg = 0;          sops[0].sem_flg = 0;
# Line 707  int user_list_try_rw_lock(int wait_sec) Line 766  int user_list_try_rw_lock(int wait_sec)
766          sops[2].sem_op = 0;      // wait until unlocked          sops[2].sem_op = 0;      // wait until unlocked
767          sops[2].sem_flg = 0;          sops[2].sem_flg = 0;
768    
 #ifdef __CYGWIN__  
         ret = semop(p_user_list_pool->semid, sops, 3);  
 #else  
         timeout.tv_sec = wait_sec;  
         timeout.tv_nsec = 0;  
   
769          ret = semtimedop(p_user_list_pool->semid, sops, 3, &timeout);          ret = semtimedop(p_user_list_pool->semid, sops, 3, &timeout);
 #endif  
770          if (ret == -1 && errno != EAGAIN && errno != EINTR)          if (ret == -1 && errno != EAGAIN && errno != EINTR)
771          {          {
772                  log_error("semop(lock write) error %d\n", errno);                  log_error("semop(lock write) error %d\n", errno);
773          }          }
774    #else
775            if (sem_timedwait(&(p_user_list_pool->sem), &timeout) == -1)
776            {
777                    if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)
778                    {
779                            log_error("sem_timedwait() error %d\n", errno);
780                    }
781                    return -1;
782            }
783    
784            if (p_user_list_pool->read_lock_count == 0 && p_user_list_pool->write_lock_count == 0)
785            {
786                    p_user_list_pool->write_lock_count++;
787            }
788            else
789            {
790                    errno = EAGAIN;
791                    ret = -1;
792            }
793    
794            if (sem_post(&(p_user_list_pool->sem)) == -1)
795            {
796                    log_error("sem_post() error %d\n", errno);
797                    return -1;
798            }
799    #endif
800    
801          return ret;          return ret;
802  }  }
803    
804  int user_list_rd_unlock(void)  int user_list_rd_unlock(void)
805  {  {
806    #ifdef HAVE_SYSTEM_V
807          struct sembuf sops[2];          struct sembuf sops[2];
808          int ret;  #endif
809            int ret = 0;
810    
811          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
812          {          {
# Line 734  int user_list_rd_unlock(void) Line 814  int user_list_rd_unlock(void)
814                  return -1;                  return -1;
815          }          }
816    
817    #ifdef HAVE_SYSTEM_V
818          sops[0].sem_num = 0;                                     // r_sem          sops[0].sem_num = 0;                                     // r_sem
819          sops[0].sem_op = -1;                                     // unlock          sops[0].sem_op = -1;                                     // unlock
820          sops[0].sem_flg = IPC_NOWAIT | SEM_UNDO; // no wait          sops[0].sem_flg = IPC_NOWAIT | SEM_UNDO; // no wait
# Line 743  int user_list_rd_unlock(void) Line 824  int user_list_rd_unlock(void)
824          {          {
825                  log_error("semop(unlock read) error %d\n", errno);                  log_error("semop(unlock read) error %d\n", errno);
826          }          }
827    #else
828            if (sem_wait(&(p_user_list_pool->sem)) == -1)
829            {
830                    if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)
831                    {
832                            log_error("sem_wait() error %d\n", errno);
833                    }
834                    return -1;
835            }
836    
837            if (p_user_list_pool->read_lock_count > 0)
838            {
839                    p_user_list_pool->read_lock_count--;
840            }
841            else
842            {
843                    log_error("read_lock_count already 0\n");
844            }
845    
846            if (sem_post(&(p_user_list_pool->sem)) == -1)
847            {
848                    log_error("sem_post() error %d\n", errno);
849                    return -1;
850            }
851    #endif
852    
853          return ret;          return ret;
854  }  }
855    
856  int user_list_rw_unlock(void)  int user_list_rw_unlock(void)
857  {  {
858    #ifdef HAVE_SYSTEM_V
859          struct sembuf sops[1];          struct sembuf sops[1];
860          int ret;  #endif
861            int ret = 0;
862    
863          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
864          {          {
# Line 758  int user_list_rw_unlock(void) Line 866  int user_list_rw_unlock(void)
866                  return -1;                  return -1;
867          }          }
868    
869    #ifdef HAVE_SYSTEM_V
870          sops[0].sem_num = 1;                                     // w_sem          sops[0].sem_num = 1;                                     // w_sem
871          sops[0].sem_op = -1;                                     // unlock          sops[0].sem_op = -1;                                     // unlock
872          sops[0].sem_flg = IPC_NOWAIT | SEM_UNDO; // no wait          sops[0].sem_flg = IPC_NOWAIT | SEM_UNDO; // no wait
# Line 767  int user_list_rw_unlock(void) Line 876  int user_list_rw_unlock(void)
876          {          {
877                  log_error("semop(unlock write) error %d\n", errno);                  log_error("semop(unlock write) error %d\n", errno);
878          }          }
879    #else
880            if (sem_wait(&(p_user_list_pool->sem)) == -1)
881            {
882                    if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)
883                    {
884                            log_error("sem_wait() error %d\n", errno);
885                    }
886                    return -1;
887            }
888    
889            if (p_user_list_pool->write_lock_count > 0)
890            {
891                    p_user_list_pool->write_lock_count--;
892            }
893            else
894            {
895                    log_error("write_lock_count already 0\n");
896            }
897    
898            if (sem_post(&(p_user_list_pool->sem)) == -1)
899            {
900                    log_error("sem_post() error %d\n", errno);
901                    return -1;
902            }
903    #endif
904    
905          return ret;          return ret;
906  }  }
# Line 796  int user_list_rd_lock(void) Line 930  int user_list_rd_lock(void)
930                          {                          {
931                                  log_error("user_list_try_rd_lock() tried %d times\n", timer);                                  log_error("user_list_try_rd_lock() tried %d times\n", timer);
932                          }                          }
933                            usleep(100 * 1000); // 0.1 second
934                  }                  }
935                  else // failed                  else // failed
936                  {                  {
# Line 832  int user_list_rw_lock(void) Line 967  int user_list_rw_lock(void)
967                          {                          {
968                                  log_error("user_list_try_rw_lock() tried %d times\n", timer);                                  log_error("user_list_try_rw_lock() tried %d times\n", timer);
969                          }                          }
970                            usleep(100 * 1000); // 0.1 second
971                  }                  }
972                  else // failed                  else // failed
973                  {                  {


Legend:
Removed lines/characters  
Changed lines/characters
  Added lines/characters

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1