/[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.42 by sysadm, Thu Nov 20 09:02:46 2025 UTC Revision 1.46 by sysadm, Thu Dec 18 02:56:01 2025 UTC
# Line 47  enum _user_list_constant_t Line 47  enum _user_list_constant_t
47  {  {
48          USER_LIST_TRY_LOCK_WAIT_TIME = 1, // second          USER_LIST_TRY_LOCK_WAIT_TIME = 1, // second
49          USER_LIST_TRY_LOCK_TIMES = 10,          USER_LIST_TRY_LOCK_TIMES = 10,
50            USER_LIST_DEAD_LOCK_TIMEOUT = 15, // second
51  };  };
52    
53  struct user_list_pool_t  struct user_list_pool_t
# Line 54  struct user_list_pool_t Line 55  struct user_list_pool_t
55          size_t shm_size;          size_t shm_size;
56  #ifndef HAVE_SYSTEM_V  #ifndef HAVE_SYSTEM_V
57          sem_t sem;          sem_t sem;
58          int read_lock_count;          uint16_t read_lock_count;
59          int write_lock_count;          uint16_t write_lock_count;
60  #else  #else
61          int semid;          int semid;
62  #endif  #endif
# Line 90  const USER_ACTION_MAP user_action_map[] Line 91  const USER_ACTION_MAP user_action_map[]
91                  {"MENU", "菜单选择"},                  {"MENU", "菜单选择"},
92                  {"POST_ARTICLE", "撰写文章"},                  {"POST_ARTICLE", "撰写文章"},
93                  {"REPLY_ARTICLE", "回复文章"},                  {"REPLY_ARTICLE", "回复文章"},
94                    {"TOP10_MENU", "十大热门"},
95                  {"USER_LIST", "查花名册"},                  {"USER_LIST", "查花名册"},
96                  {"USER_ONLINE", "环顾四周"},                  {"USER_ONLINE", "环顾四周"},
97                  {"VIEW_ARTICLE", "阅读文章"},                  {"VIEW_ARTICLE", "阅读文章"},
# Line 104  static int user_list_rd_unlock(void); Line 106  static int user_list_rd_unlock(void);
106  static int user_list_rw_unlock(void);  static int user_list_rw_unlock(void);
107  static int user_list_rd_lock(void);  static int user_list_rd_lock(void);
108  static int user_list_rw_lock(void);  static int user_list_rw_lock(void);
109    #ifndef HAVE_SYSTEM_V
110    static int user_list_reset_lock(void);
111    #endif
112    
113  static int user_list_load(MYSQL *db, USER_LIST *p_list);  static int user_list_load(MYSQL *db, USER_LIST *p_list);
114  static int user_online_list_load(MYSQL *db, USER_ONLINE_LIST *p_online_list);  static int user_online_list_load(MYSQL *db, USER_ONLINE_LIST *p_online_list);
# Line 235  int user_list_load(MYSQL *db, USER_LIST Line 240  int user_list_load(MYSQL *db, USER_LIST
240    
241                  qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);                  qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
242    
243  #ifdef _DEBUG                  log_debug("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);
                 log_error("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);  
 #endif  
244          }          }
245    
246          p_list->user_count = i;          p_list->user_count = i;
247    
248  #ifdef _DEBUG          log_debug("Loaded %d users\n", p_list->user_count);
         log_error("Loaded %d users\n", p_list->user_count);  
 #endif  
249    
250  cleanup:  cleanup:
251          mysql_free_result(rs);          mysql_free_result(rs);
# Line 829  int user_list_rd_unlock(void) Line 830  int user_list_rd_unlock(void)
830          {          {
831                  if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)                  if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)
832                  {                  {
833                          log_error("sem_timedwait() error %d\n", errno);                          log_error("sem_wait() error %d\n", errno);
834                  }                  }
835                  return -1;                  return -1;
836          }          }
# Line 881  int user_list_rw_unlock(void) Line 882  int user_list_rw_unlock(void)
882          {          {
883                  if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)                  if (errno != ETIMEDOUT && errno != EAGAIN && errno != EINTR)
884                  {                  {
885                          log_error("sem_timedwait() error %d\n", errno);                          log_error("sem_wait() error %d\n", errno);
886                  }                  }
887                  return -1;                  return -1;
888          }          }
# Line 909  int user_list_rd_lock(void) Line 910  int user_list_rd_lock(void)
910  {  {
911          int timer = 0;          int timer = 0;
912          int ret = -1;          int ret = -1;
913            time_t tm_first_failure = 0;
914    
915          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
916          {          {
# Line 929  int user_list_rd_lock(void) Line 931  int user_list_rd_lock(void)
931                          if (timer % USER_LIST_TRY_LOCK_TIMES == 0)                          if (timer % USER_LIST_TRY_LOCK_TIMES == 0)
932                          {                          {
933                                  log_error("user_list_try_rd_lock() tried %d times\n", timer);                                  log_error("user_list_try_rd_lock() tried %d times\n", timer);
934    
935                                    if (time(NULL) - tm_first_failure >= USER_LIST_DEAD_LOCK_TIMEOUT)
936                                    {
937                                            log_error("Unable to acquire rw_lock for %d seconds\n", time(NULL) - tm_first_failure);
938    #ifndef HAVE_SYSTEM_V
939                                            user_list_reset_lock();
940                                            log_error("Reset POSIX semaphore to resolve dead lock\n");
941    #endif
942                                            break;
943                                    }
944                          }                          }
945                          usleep(100 * 1000); // 0.1 second                          usleep(100 * 1000); // 0.1 second
946                  }                  }
# Line 946  int user_list_rw_lock(void) Line 958  int user_list_rw_lock(void)
958  {  {
959          int timer = 0;          int timer = 0;
960          int ret = -1;          int ret = -1;
961            time_t tm_first_failure = 0;
962    
963          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
964          {          {
# Line 966  int user_list_rw_lock(void) Line 979  int user_list_rw_lock(void)
979                          if (timer % USER_LIST_TRY_LOCK_TIMES == 0)                          if (timer % USER_LIST_TRY_LOCK_TIMES == 0)
980                          {                          {
981                                  log_error("user_list_try_rw_lock() tried %d times\n", timer);                                  log_error("user_list_try_rw_lock() tried %d times\n", timer);
982    
983                                    if (time(NULL) - tm_first_failure >= USER_LIST_DEAD_LOCK_TIMEOUT)
984                                    {
985                                            log_error("Unable to acquire rw_lock for %d seconds\n", time(NULL) - tm_first_failure);
986    #ifndef HAVE_SYSTEM_V
987                                            user_list_reset_lock();
988                                            log_error("Reset POSIX semaphore to resolve dead lock\n");
989    #endif
990                                            break;
991                                    }
992                          }                          }
993                          usleep(100 * 1000); // 0.1 second                          usleep(100 * 1000); // 0.1 second
994                  }                  }
# Line 979  int user_list_rw_lock(void) Line 1002  int user_list_rw_lock(void)
1002          return ret;          return ret;
1003  }  }
1004    
1005    #ifndef HAVE_SYSTEM_V
1006    int user_list_reset_lock(void)
1007    {
1008            if (p_user_list_pool == NULL)
1009            {
1010                    log_error("p_user_list_pool not initialized\n");
1011                    return -1;
1012            }
1013    
1014            if (sem_destroy(&(p_user_list_pool->sem)) == -1)
1015            {
1016                    log_error("sem_destroy() error (%d)\n", errno);
1017            }
1018    
1019            p_user_list_pool->read_lock_count = 0;
1020            p_user_list_pool->write_lock_count = 0;
1021    
1022            if (sem_init(&(p_user_list_pool->sem), 1, 1) == -1)
1023            {
1024                    log_error("sem_init() error (%d)\n", errno);
1025            }
1026    
1027            return 0;
1028    }
1029    #endif
1030    
1031  int query_user_list(int page_id, USER_INFO *p_users, int *p_user_count, int *p_page_count)  int query_user_list(int page_id, USER_INFO *p_users, int *p_user_count, int *p_page_count)
1032  {  {
1033          int ret = 0;          int ret = 0;
# Line 1308  int query_user_info_by_username(const ch Line 1357  int query_user_info_by_username(const ch
1357    
1358          if (strncasecmp(username_prefix, p_user_list_pool->user_list[p_user_list_pool->user_list_index_current].users[left].username, prefix_len) == 0) // Found          if (strncasecmp(username_prefix, p_user_list_pool->user_list[p_user_list_pool->user_list_index_current].users[left].username, prefix_len) == 0) // Found
1359          {          {
1360  #ifdef _DEBUG                  log_debug("Debug: match found, pos=%d\n", left);
                 log_error("Debug: match found, pos=%d\n", left);  
 #endif  
1361    
1362                  left_save = left;                  left_save = left;
1363                  right = left;                  right = left;
# Line 1336  int query_user_info_by_username(const ch Line 1383  int query_user_info_by_username(const ch
1383                          }                          }
1384                  }                  }
1385    
1386  #ifdef _DEBUG                  log_debug("Debug: first match found, pos=%d\n", right);
                 log_error("Debug: first match found, pos=%d\n", right);  
 #endif  
1387    
1388                  left = left_save;                  left = left_save;
1389                  left_save = right;                  left_save = right;
# Line 1364  int query_user_info_by_username(const ch Line 1409  int query_user_info_by_username(const ch
1409                          }                          }
1410                  }                  }
1411    
1412  #ifdef _DEBUG                  log_debug("Debug: last match found, pos=%d\n", left);
                 log_error("Debug: last match found, pos=%d\n", left);  
 #endif  
1413    
1414                  right = left;                  right = left;
1415                  left = left_save;                  left = left_save;


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

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