/[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.8 by sysadm, Wed Oct 22 07:16:48 2025 UTC Revision 1.16 by sysadm, Thu Oct 23 01:29:43 2025 UTC
# Line 83  const USER_ACTION_MAP user_action_map[] Line 83  const USER_ACTION_MAP user_action_map[]
83    
84  const int user_action_map_size = sizeof(user_action_map) / sizeof(USER_ACTION_MAP);  const int user_action_map_size = sizeof(user_action_map) / sizeof(USER_ACTION_MAP);
85    
 static int user_list_try_rd_lock(int semid, int wait_sec);  
 static int user_list_try_rw_lock(int semid, int wait_sec);  
 static int user_list_rd_unlock(int semid);  
 static int user_list_rw_unlock(int semid);  
 static int user_list_rd_lock(int semid);  
 static int user_list_rw_lock(int semid);  
   
86  static int user_list_load(MYSQL *db, USER_LIST *p_list);  static int user_list_load(MYSQL *db, USER_LIST *p_list);
87  static int user_online_list_load(MYSQL *db, USER_ONLINE_LIST *p_list);  static int user_online_list_load(MYSQL *db, USER_ONLINE_LIST *p_list);
88    
# Line 106  static int user_info_index_uid_comp(cons Line 99  static int user_info_index_uid_comp(cons
99          {          {
100                  return 1;                  return 1;
101          }          }
102            else if (p1->id < p2->id)
103            {
104                    return -1;
105            }
106            else if (p1->id > p2->id)
107            {
108                    return 1;
109            }
110          return 0;          return 0;
111  }  }
112    
# Line 116  int user_list_load(MYSQL *db, USER_LIST Line 117  int user_list_load(MYSQL *db, USER_LIST
117          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
118          int ret = 0;          int ret = 0;
119          int i;          int i;
120            int j;
121            int32_t last_uid;
122            size_t intro_buf_offset;
123            size_t intro_len;
124    
125          if (db == NULL || p_list == NULL)          if (db == NULL || p_list == NULL)
126          {          {
# Line 123  int user_list_load(MYSQL *db, USER_LIST Line 128  int user_list_load(MYSQL *db, USER_LIST
128                  return -1;                  return -1;
129          }          }
130    
131            if (p_list->user_count > 0)
132            {
133                    last_uid = p_list->users[p_list->user_count - 1].uid;
134            }
135            else
136            {
137                    last_uid = -1;
138            }
139    
140          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
141                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, "                           "SELECT user_list.UID AS UID, username, nickname, gender, gender_pub, life, exp, visit_count, "
142                           "UNIX_TIMESTAMP(signup_dt), UNIX_TIMESTAMP(last_login_dt), UNIX_TIMESTAMP(birthday) "                           "UNIX_TIMESTAMP(signup_dt), UNIX_TIMESTAMP(last_login_dt), UNIX_TIMESTAMP(birthday), `introduction` "
143                           "FROM user_list INNER JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "                           "FROM user_list INNER JOIN user_pubinfo ON user_list.UID = user_pubinfo.UID "
144                           "INNER JOIN user_reginfo ON user_list.UID = user_reginfo.UID "                           "INNER JOIN user_reginfo ON user_list.UID = user_reginfo.UID "
145                           "WHERE enable ORDER BY username");                           "WHERE enable ORDER BY username");
# Line 144  int user_list_load(MYSQL *db, USER_LIST Line 158  int user_list_load(MYSQL *db, USER_LIST
158                  goto cleanup;                  goto cleanup;
159          }          }
160    
161            intro_buf_offset = 0;
162          i = 0;          i = 0;
163          while ((row = mysql_fetch_row(rs)))          while ((row = mysql_fetch_row(rs)))
164          {          {
# Line 158  int user_list_load(MYSQL *db, USER_LIST Line 173  int user_list_load(MYSQL *db, USER_LIST
173                  p_list->users[i].gender_pub = (int8_t)(row[4] == NULL ? 0 : atoi(row[4]));                  p_list->users[i].gender_pub = (int8_t)(row[4] == NULL ? 0 : atoi(row[4]));
174                  p_list->users[i].life = (row[5] == NULL ? 0 : atoi(row[5]));                  p_list->users[i].life = (row[5] == NULL ? 0 : atoi(row[5]));
175                  p_list->users[i].exp = (row[6] == NULL ? 0 : atoi(row[6]));                  p_list->users[i].exp = (row[6] == NULL ? 0 : atoi(row[6]));
176                  p_list->users[i].signup_dt = (row[7] == NULL ? 0 : atol(row[7]));                  p_list->users[i].visit_count = (row[7] == NULL ? 0 : atoi(row[7]));
177                  p_list->users[i].last_login_dt = (row[8] == NULL ? 0 : atol(row[8]));                  p_list->users[i].signup_dt = (row[8] == NULL ? 0 : atol(row[8]));
178                  p_list->users[i].birthday = (row[9] == NULL ? 0 : atol(row[9]));                  p_list->users[i].last_login_dt = (row[9] == NULL ? 0 : atol(row[9]));
179                    p_list->users[i].birthday = (row[10] == NULL ? 0 : atol(row[10]));
180                  // index                  intro_len = strlen((row[11] == NULL ? "" : row[11]));
181                  p_list->index_uid[i].uid = p_list->users[i].uid;                  if (intro_len >= sizeof(p_list->user_intro_buf) - 1 - intro_buf_offset)
182                  p_list->index_uid[i].id = i;                  {
183                            log_error("OOM for user introduction: len=%d, i=%d\n", intro_len, i);
184                            break;
185                    }
186                    memcpy(p_list->user_intro_buf + intro_buf_offset,
187                               (row[11] == NULL ? "" : row[11]),
188                               intro_len + 1);
189                    p_list->users[i].intro = p_list->user_intro_buf + intro_buf_offset;
190                    intro_buf_offset += (intro_len + 1);
191    
192                  i++;                  i++;
193                  if (i >= BBS_max_user_count)                  if (i >= BBS_max_user_count)
# Line 176  int user_list_load(MYSQL *db, USER_LIST Line 199  int user_list_load(MYSQL *db, USER_LIST
199          mysql_free_result(rs);          mysql_free_result(rs);
200          rs = NULL;          rs = NULL;
201    
202          p_list->user_count = i;          if (i != p_list->user_count || p_list->users[i - 1].uid != last_uid) // Count of users changed
203            {
204                    // Rebuild index
205                    for (j = 0; j < i; j++)
206                    {
207                            p_list->index_uid[j].uid = p_list->users[j].uid;
208                            p_list->index_uid[j].id = j;
209                    }
210    
211          // Sort index                  qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
212          qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);  
213    #ifdef _DEBUG
214                    log_error("Rebuild index of %d users, last_uid=%d\n", i, p_list->users[i - 1].uid);
215    #endif
216            }
217    
218            p_list->user_count = i;
219    
220  #ifdef _DEBUG  #ifdef _DEBUG
221          log_error("Loaded %d users\n", p_list->user_count);          log_error("Loaded %d users\n", p_list->user_count);
# Line 198  int user_online_list_load(MYSQL *db, USE Line 234  int user_online_list_load(MYSQL *db, USE
234          char sql[SQL_BUFFER_LEN];          char sql[SQL_BUFFER_LEN];
235          int ret = 0;          int ret = 0;
236          int i;          int i;
237            int j;
238    
239          if (db == NULL || p_list == NULL)          if (db == NULL || p_list == NULL)
240          {          {
# Line 208  int user_online_list_load(MYSQL *db, USE Line 245  int user_online_list_load(MYSQL *db, USE
245          snprintf(sql, sizeof(sql),          snprintf(sql, sizeof(sql),
246                           "SELECT SID, UID, ip, current_action, UNIX_TIMESTAMP(login_tm), "                           "SELECT SID, UID, ip, current_action, UNIX_TIMESTAMP(login_tm), "
247                           "UNIX_TIMESTAMP(last_tm) FROM user_online "                           "UNIX_TIMESTAMP(last_tm) FROM user_online "
248                           "WHERE last_tm >= SUBDATE(NOW(), INTERVAL %d SECOND) "                           "WHERE last_tm >= SUBDATE(NOW(), INTERVAL %d SECOND) AND UID <> 0 "
249                           "ORDER BY last_tm DESC",                           "ORDER BY last_tm DESC",
250                           BBS_user_off_line);                           BBS_user_off_line);
251    
# Line 233  int user_online_list_load(MYSQL *db, USE Line 270  int user_online_list_load(MYSQL *db, USE
270                  strncpy(p_list->users[i].session_id, row[0], sizeof(p_list->users[i].session_id) - 1);                  strncpy(p_list->users[i].session_id, row[0], sizeof(p_list->users[i].session_id) - 1);
271                  p_list->users[i].session_id[sizeof(p_list->users[i].session_id) - 1] = '\0';                  p_list->users[i].session_id[sizeof(p_list->users[i].session_id) - 1] = '\0';
272    
273                  if ((ret = query_user_info_by_uid(atoi(row[1]), &(p_list->users[i].user_info))) < 0)                  if ((ret = query_user_info_by_uid(atoi(row[1]), &(p_list->users[i].user_info))) <= 0)
274                  {                  {
275                          log_error("query_user_info(%d) error\n", atoi(row[1]));                          log_error("query_user_info_by_uid(%d) error\n", atoi(row[1]));
276                          continue;                          continue;
277                  }                  }
                 else if (ret == 0) // Guest  
                 {  
                         p_list->users[i].user_info.id = -1;  
                         p_list->users[i].user_info.uid = 0;  
                         strncpy(p_list->users[i].user_info.username, "guest", sizeof(p_list->users[i].user_info.username) - 1);  
                         p_list->users[i].user_info.username[sizeof(p_list->users[i].user_info.username) - 1] = '\0';  
                         strncpy(p_list->users[i].user_info.nickname, "Guest", sizeof(p_list->users[i].user_info.nickname) - 1);  
                         p_list->users[i].user_info.nickname[sizeof(p_list->users[i].user_info.nickname) - 1] = '\0';  
                         p_list->users[i].user_info.gender = 'M';  
                         p_list->users[i].user_info.gender_pub = 0;  
                         p_list->users[i].user_info.life = 150;  
                         p_list->users[i].user_info.exp = 0;  
                         p_list->users[i].user_info.signup_dt = 0;  
                         p_list->users[i].user_info.last_login_dt = 0;  
                         p_list->users[i].user_info.birthday = 0;  
                 }  
278    
279                  strncpy(p_list->users[i].ip, row[2], sizeof(p_list->users[i].ip) - 1);                  strncpy(p_list->users[i].ip, row[2], sizeof(p_list->users[i].ip) - 1);
280                  p_list->users[i].ip[sizeof(p_list->users[i].ip) - 1] = '\0';                  p_list->users[i].ip[sizeof(p_list->users[i].ip) - 1] = '\0';
# Line 285  int user_online_list_load(MYSQL *db, USE Line 306  int user_online_list_load(MYSQL *db, USE
306          mysql_free_result(rs);          mysql_free_result(rs);
307          rs = NULL;          rs = NULL;
308    
309            if (i > 0)
310            {
311                    // Rebuild index
312                    for (j = 0; j < i; j++)
313                    {
314                            p_list->index_uid[j].uid = p_list->users[j].user_info.uid;
315                            p_list->index_uid[j].id = j;
316                    }
317    
318                    qsort(p_list->index_uid, (size_t)i, sizeof(USER_INFO_INDEX_UID), user_info_index_uid_comp);
319    
320    #ifdef _DEBUG
321                    log_error("Rebuild index of %d online users\n", i);
322    #endif
323            }
324    
325          p_list->user_count = i;          p_list->user_count = i;
326    
327  #ifdef _DEBUG  #ifdef _DEBUG
328          log_error("Loaded %d users\n", p_list->user_count);          log_error("Loaded %d online users\n", p_list->user_count);
329  #endif  #endif
330    
331  cleanup:  cleanup:
# Line 470  int user_list_pool_reload(int online_use Line 507  int user_list_pool_reload(int online_use
507          MYSQL *db = NULL;          MYSQL *db = NULL;
508          USER_LIST *p_tmp;          USER_LIST *p_tmp;
509          USER_ONLINE_LIST *p_online_tmp;          USER_ONLINE_LIST *p_online_tmp;
510            int ret = 0;
511    
512          if (p_user_list_pool == NULL)          if (p_user_list_pool == NULL)
513          {          {
# Line 489  int user_list_pool_reload(int online_use Line 527  int user_list_pool_reload(int online_use
527                  if (user_online_list_load(db, p_user_list_pool->p_online_new) < 0)                  if (user_online_list_load(db, p_user_list_pool->p_online_new) < 0)
528                  {                  {
529                          log_error("user_online_list_load() error\n");                          log_error("user_online_list_load() error\n");
530                          return -2;                          ret = -2;
531                            goto cleanup;
532                  }                  }
533          }          }
534          else          else
# Line 497  int user_list_pool_reload(int online_use Line 536  int user_list_pool_reload(int online_use
536                  if (user_list_load(db, p_user_list_pool->p_new) < 0)                  if (user_list_load(db, p_user_list_pool->p_new) < 0)
537                  {                  {
538                          log_error("user_list_load() error\n");                          log_error("user_list_load() error\n");
539                          return -2;                          ret = -2;
540                            goto cleanup;
541                  }                  }
542          }          }
543    
544          mysql_close(db);          mysql_close(db);
545            db = NULL;
546    
547          if (user_list_rw_lock(p_user_list_pool->semid) < 0)          if (user_list_rw_lock(p_user_list_pool->semid) < 0)
548          {          {
549                  log_error("user_list_rw_lock() error\n");                  log_error("user_list_rw_lock() error\n");
550                  return -3;                  ret = -3;
551                    goto cleanup;
552          }          }
553    
554          if (online_user)          if (online_user)
# Line 527  int user_list_pool_reload(int online_use Line 569  int user_list_pool_reload(int online_use
569          if (user_list_rw_unlock(p_user_list_pool->semid) < 0)          if (user_list_rw_unlock(p_user_list_pool->semid) < 0)
570          {          {
571                  log_error("user_list_rw_unlock() error\n");                  log_error("user_list_rw_unlock() error\n");
572                  return -3;                  ret = -3;
573                    goto cleanup;
574          }          }
575    
576          return 0;  cleanup:
577            mysql_close(db);
578    
579            return ret;
580  }  }
581    
582  int user_list_try_rd_lock(int semid, int wait_sec)  int user_list_try_rd_lock(int semid, int wait_sec)
# Line 695  int query_user_list(int page_id, USER_IN Line 741  int query_user_list(int page_id, USER_IN
741                  return -1;                  return -1;
742          }          }
743    
744            *p_user_count = 0;
745            *p_page_count = 0;
746    
747          // acquire lock of user list          // acquire lock of user list
748          if (user_list_rd_lock(p_user_list_pool->semid) < 0)          if (user_list_rd_lock(p_user_list_pool->semid) < 0)
749          {          {
# Line 748  int query_user_online_list(int page_id, Line 797  int query_user_online_list(int page_id,
797                  return -1;                  return -1;
798          }          }
799    
800            *p_user_count = 0;
801            *p_page_count = 0;
802    
803          // acquire lock of user list          // acquire lock of user list
804          if (user_list_rd_lock(p_user_list_pool->semid) < 0)          if (user_list_rd_lock(p_user_list_pool->semid) < 0)
805          {          {
# Line 869  int query_user_info_by_uid(int32_t uid, Line 921  int query_user_info_by_uid(int32_t uid,
921          if (uid == p_user_list_pool->p_current->index_uid[left].uid) // Found          if (uid == p_user_list_pool->p_current->index_uid[left].uid) // Found
922          {          {
923                  id = p_user_list_pool->p_current->index_uid[left].id;                  id = p_user_list_pool->p_current->index_uid[left].id;
924                  if ((ret = query_user_info(id, p_user)) <= 0)                  *p_user = p_user_list_pool->p_current->users[id];
925                  {                  ret = 1;
                         log_error("query_user_info(id=%d) error: %d\n", id, ret);  
                 }  
                 else  
                 {  
                         ret = 1;  
                 }  
926          }          }
927    
928          // release lock of user list          // release lock of user list
# Line 913  int query_user_online_info(int32_t id, U Line 959  int query_user_online_info(int32_t id, U
959          }          }
960    
961          // release lock of user list          // release lock of user list
962            if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
963            {
964                    log_error("user_list_rd_unlock() error\n");
965                    ret = -1;
966            }
967    
968            return ret;
969    }
970    
971    int query_user_online_info_by_uid(int32_t uid, USER_ONLINE_INFO *p_users, int *p_user_cnt, int start_id)
972    {
973            int left;
974            int right;
975            int mid;
976            int32_t id;
977            int ret = 0;
978            int i;
979    
980            if (p_users == NULL || p_user_cnt == NULL)
981            {
982                    log_error("NULL pointer error\n");
983                    return -1;
984            }
985    
986            // acquire lock of user list
987            if (user_list_rd_lock(p_user_list_pool->semid) < 0)
988            {
989                    log_error("user_list_rd_lock() error\n");
990                    return -2;
991            }
992    
993            left = start_id;
994            right = p_user_list_pool->p_online_current->user_count - 1;
995    
996            while (left < right)
997            {
998                    mid = (left + right) / 2;
999                    if (uid < p_user_list_pool->p_online_current->index_uid[mid].uid)
1000                    {
1001                            right = mid;
1002                    }
1003                    else if (uid > p_user_list_pool->p_online_current->index_uid[mid].uid)
1004                    {
1005                            left = mid + 1;
1006                    }
1007                    else // if (uid == p_user_list_pool->p_online_current->index_uid[mid].uid)
1008                    {
1009                            left = mid;
1010                            break;
1011                    }
1012            }
1013    
1014            if (uid == p_user_list_pool->p_online_current->index_uid[left].uid)
1015            {
1016                    right = left;
1017                    left = start_id;
1018    
1019                    while (left < right)
1020                    {
1021                            mid = (left + right) / 2;
1022                            if (uid - 1 < p_user_list_pool->p_online_current->index_uid[mid].uid)
1023                            {
1024                                    right = mid;
1025                            }
1026                            else // if (uid - 1 >= p_user_list_pool->p_online_current->index_uid[mid].uid)
1027                            {
1028                                    left = mid + 1;
1029                            }
1030                    }
1031    
1032                    for (i = 0;
1033                             left < p_user_list_pool->p_online_current->user_count && i < *p_user_cnt &&
1034                             uid == p_user_list_pool->p_online_current->index_uid[left].uid;
1035                             left++, i++)
1036                    {
1037                            id = p_user_list_pool->p_online_current->index_uid[left].id;
1038                            p_users[i] = p_user_list_pool->p_online_current->users[id];
1039                    }
1040    
1041                    if (i > 0)
1042                    {
1043                            *p_user_cnt = i;
1044                            ret = 1;
1045                    }
1046            }
1047    
1048            // release lock of user list
1049          if (user_list_rd_unlock(p_user_list_pool->semid) < 0)          if (user_list_rd_unlock(p_user_list_pool->semid) < 0)
1050          {          {
1051                  log_error("user_list_rd_unlock() error\n");                  log_error("user_list_rd_unlock() error\n");


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

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