| 41 |
{ |
{ |
| 42 |
SECTION_TRY_LOCK_WAIT_TIME = 1, // second |
SECTION_TRY_LOCK_WAIT_TIME = 1, // second |
| 43 |
SECTION_TRY_LOCK_TIMES = 10, |
SECTION_TRY_LOCK_TIMES = 10, |
| 44 |
|
SECTION_DEAD_LOCK_TIMEOUT = 15, // second |
| 45 |
|
|
| 46 |
ARTICLE_BLOCK_PER_SHM = 1000, // sizeof(ARTICLE_BLOCK) * ARTICLE_BLOCK_PER_SHM is the size of each shm segment to allocate |
ARTICLE_BLOCK_PER_SHM = 1000, // sizeof(ARTICLE_BLOCK) * ARTICLE_BLOCK_PER_SHM is the size of each shm segment to allocate |
| 47 |
ARTICLE_BLOCK_SHM_COUNT_LIMIT = 80, // limited by length (8-bit) of proj_id in ftok(path, proj_id) |
ARTICLE_BLOCK_SHM_COUNT_LIMIT = 80, // limited by length (8-bit) of proj_id in ftok(path, proj_id) |
| 81 |
static char section_list_shm_name[FILE_NAME_LEN]; |
static char section_list_shm_name[FILE_NAME_LEN]; |
| 82 |
SECTION_LIST_POOL *p_section_list_pool = NULL; |
SECTION_LIST_POOL *p_section_list_pool = NULL; |
| 83 |
|
|
| 84 |
|
#ifndef HAVE_SYSTEM_V |
| 85 |
|
static int section_list_reset_lock(SECTION_LIST *p_section); |
| 86 |
|
#endif |
| 87 |
|
|
| 88 |
int article_block_init(const char *filename, int block_count) |
int article_block_init(const char *filename, int block_count) |
| 89 |
{ |
{ |
| 90 |
char filepath[FILE_PATH_LEN]; |
char filepath[FILE_PATH_LEN]; |
| 251 |
|
|
| 252 |
int set_article_block_shm_readonly(void) |
int set_article_block_shm_readonly(void) |
| 253 |
{ |
{ |
| 254 |
int i; |
// int i; |
| 255 |
|
|
| 256 |
if (p_article_block_pool == NULL) |
if (p_article_block_pool == NULL) |
| 257 |
{ |
{ |
| 259 |
return -1; |
return -1; |
| 260 |
} |
} |
| 261 |
|
|
| 262 |
for (i = 0; i < p_article_block_pool->shm_count; i++) |
// for (i = 0; i < p_article_block_pool->shm_count; i++) |
| 263 |
{ |
// { |
| 264 |
if ((p_article_block_pool->shm_pool + i)->p_shm != NULL && |
// if ((p_article_block_pool->shm_pool + i)->p_shm != NULL && |
| 265 |
mprotect((p_article_block_pool->shm_pool + i)->p_shm, (p_article_block_pool->shm_pool + i)->shm_size, PROT_READ) < 0) |
// mprotect((p_article_block_pool->shm_pool + i)->p_shm, (p_article_block_pool->shm_pool + i)->shm_size, PROT_READ) < 0) |
| 266 |
{ |
// { |
| 267 |
log_error("mprotect() error (%d)\n", errno); |
// log_error("mprotect() error (%d)\n", errno); |
| 268 |
return -2; |
// return -2; |
| 269 |
} |
// } |
| 270 |
} |
// } |
| 271 |
|
|
| 272 |
if (p_article_block_pool != NULL && |
if (p_article_block_pool != NULL && |
| 273 |
mprotect(p_article_block_pool, p_article_block_pool->shm_size, PROT_READ) < 0) |
mprotect(p_article_block_pool, p_article_block_pool->shm_size, PROT_READ) < 0) |
| 1031 |
return affected_count; |
return affected_count; |
| 1032 |
} |
} |
| 1033 |
|
|
| 1034 |
|
int section_list_set_article_excerption(SECTION_LIST *p_section, int32_t aid, int8_t excerption) |
| 1035 |
|
{ |
| 1036 |
|
ARTICLE *p_article; |
| 1037 |
|
|
| 1038 |
|
if (p_section == NULL) |
| 1039 |
|
{ |
| 1040 |
|
log_error("NULL pointer error\n"); |
| 1041 |
|
return -1; |
| 1042 |
|
} |
| 1043 |
|
|
| 1044 |
|
p_article = article_block_find_by_aid(aid); |
| 1045 |
|
if (p_article == NULL) |
| 1046 |
|
{ |
| 1047 |
|
return -1; // Not found |
| 1048 |
|
} |
| 1049 |
|
|
| 1050 |
|
if (p_section->sid != p_article->sid) |
| 1051 |
|
{ |
| 1052 |
|
log_error("Inconsistent section sid %d != article sid %d\n", p_section->sid, p_article->sid); |
| 1053 |
|
return -2; |
| 1054 |
|
} |
| 1055 |
|
|
| 1056 |
|
if (p_article->excerption == excerption) |
| 1057 |
|
{ |
| 1058 |
|
return 0; // Already set |
| 1059 |
|
} |
| 1060 |
|
|
| 1061 |
|
p_article->excerption = excerption; |
| 1062 |
|
|
| 1063 |
|
return 1; |
| 1064 |
|
} |
| 1065 |
|
|
| 1066 |
int section_list_update_article_ontop(SECTION_LIST *p_section, ARTICLE *p_article) |
int section_list_update_article_ontop(SECTION_LIST *p_section, ARTICLE *p_article) |
| 1067 |
{ |
{ |
| 1068 |
int i; |
int i; |
| 2024 |
int timer = 0; |
int timer = 0; |
| 2025 |
int sid = (p_section == NULL ? 0 : p_section->sid); |
int sid = (p_section == NULL ? 0 : p_section->sid); |
| 2026 |
int ret = -1; |
int ret = -1; |
| 2027 |
|
time_t tm_first_failure = 0; |
| 2028 |
|
|
| 2029 |
while (!SYS_server_exit) |
while (!SYS_server_exit) |
| 2030 |
{ |
{ |
| 2035 |
} |
} |
| 2036 |
else if (errno == EAGAIN || errno == EINTR) // retry |
else if (errno == EAGAIN || errno == EINTR) // retry |
| 2037 |
{ |
{ |
| 2038 |
|
// Dead lock detection |
| 2039 |
|
if (tm_first_failure == 0) |
| 2040 |
|
{ |
| 2041 |
|
time(&tm_first_failure); |
| 2042 |
|
} |
| 2043 |
|
|
| 2044 |
timer++; |
timer++; |
| 2045 |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
| 2046 |
{ |
{ |
| 2047 |
log_error("section_list_try_rd_lock() tried %d times on section %d\n", timer, sid); |
log_error("section_list_try_rd_lock() tried %d times on section %d\n", timer, sid); |
| 2048 |
|
if (time(NULL) - tm_first_failure >= SECTION_DEAD_LOCK_TIMEOUT) |
| 2049 |
|
{ |
| 2050 |
|
log_error("Unable to acquire rd_lock for %d seconds\n", time(NULL) - tm_first_failure); |
| 2051 |
|
#ifndef HAVE_SYSTEM_V |
| 2052 |
|
section_list_reset_lock(p_section); |
| 2053 |
|
log_error("Reset POSIX semaphore to resolve dead lock\n"); |
| 2054 |
|
#endif |
| 2055 |
|
break; |
| 2056 |
|
} |
| 2057 |
} |
} |
| 2058 |
usleep(100 * 1000); // 0.1 second |
usleep(100 * 1000); // 0.1 second |
| 2059 |
} |
} |
| 2072 |
int timer = 0; |
int timer = 0; |
| 2073 |
int sid = (p_section == NULL ? 0 : p_section->sid); |
int sid = (p_section == NULL ? 0 : p_section->sid); |
| 2074 |
int ret = -1; |
int ret = -1; |
| 2075 |
|
time_t tm_first_failure = 0; |
| 2076 |
|
|
| 2077 |
while (!SYS_server_exit) |
while (!SYS_server_exit) |
| 2078 |
{ |
{ |
| 2083 |
} |
} |
| 2084 |
else if (errno == EAGAIN || errno == EINTR) // retry |
else if (errno == EAGAIN || errno == EINTR) // retry |
| 2085 |
{ |
{ |
| 2086 |
|
// Dead lock detection |
| 2087 |
|
if (tm_first_failure == 0) |
| 2088 |
|
{ |
| 2089 |
|
time(&tm_first_failure); |
| 2090 |
|
} |
| 2091 |
|
|
| 2092 |
timer++; |
timer++; |
| 2093 |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
| 2094 |
{ |
{ |
| 2095 |
log_error("section_list_try_rw_lock() tried %d times on section %d\n", timer, sid); |
log_error("section_list_try_rw_lock() tried %d times on section %d\n", timer, sid); |
| 2096 |
|
if (time(NULL) - tm_first_failure >= SECTION_DEAD_LOCK_TIMEOUT) |
| 2097 |
|
{ |
| 2098 |
|
log_error("Unable to acquire rw_lock for %d seconds\n", time(NULL) - tm_first_failure); |
| 2099 |
|
#ifndef HAVE_SYSTEM_V |
| 2100 |
|
section_list_reset_lock(p_section); |
| 2101 |
|
log_error("Reset POSIX semaphore to resolve dead lock\n"); |
| 2102 |
|
#endif |
| 2103 |
|
break; |
| 2104 |
|
} |
| 2105 |
} |
} |
| 2106 |
usleep(100 * 1000); // 0.1 second |
usleep(100 * 1000); // 0.1 second |
| 2107 |
} |
} |
| 2114 |
|
|
| 2115 |
return ret; |
return ret; |
| 2116 |
} |
} |
| 2117 |
|
|
| 2118 |
|
#ifndef HAVE_SYSTEM_V |
| 2119 |
|
int section_list_reset_lock(SECTION_LIST *p_section) |
| 2120 |
|
{ |
| 2121 |
|
int index; |
| 2122 |
|
|
| 2123 |
|
if (p_section == NULL) |
| 2124 |
|
{ |
| 2125 |
|
log_error("NULL pointer error\n"); |
| 2126 |
|
return -1; |
| 2127 |
|
} |
| 2128 |
|
|
| 2129 |
|
index = get_section_index(p_section); |
| 2130 |
|
if (index < 0) |
| 2131 |
|
{ |
| 2132 |
|
return -2; |
| 2133 |
|
} |
| 2134 |
|
|
| 2135 |
|
if (sem_destroy(&(p_section_list_pool->sem[index])) == -1) |
| 2136 |
|
{ |
| 2137 |
|
log_error("sem_destroy(sem[%d]) error (%d)\n", index, errno); |
| 2138 |
|
} |
| 2139 |
|
|
| 2140 |
|
p_section_list_pool->read_lock_count[index] = 0; |
| 2141 |
|
p_section_list_pool->write_lock_count[index] = 0; |
| 2142 |
|
|
| 2143 |
|
if (sem_init(&(p_section_list_pool->sem[index]), 1, 1) == -1) |
| 2144 |
|
{ |
| 2145 |
|
log_error("sem_init(sem[%d]) error (%d)\n", index, errno); |
| 2146 |
|
} |
| 2147 |
|
|
| 2148 |
|
if (index != BBS_max_section) |
| 2149 |
|
{ |
| 2150 |
|
if (sem_destroy(&(p_section_list_pool->sem[BBS_max_section])) == -1) |
| 2151 |
|
{ |
| 2152 |
|
log_error("sem_destroy(sem[%d]) error (%d)\n", BBS_max_section, errno); |
| 2153 |
|
} |
| 2154 |
|
|
| 2155 |
|
p_section_list_pool->read_lock_count[BBS_max_section] = 0; |
| 2156 |
|
p_section_list_pool->write_lock_count[BBS_max_section] = 0; |
| 2157 |
|
|
| 2158 |
|
if (sem_init(&(p_section_list_pool->sem[BBS_max_section]), 1, 1) == -1) |
| 2159 |
|
{ |
| 2160 |
|
log_error("sem_init(sem[%d]) error (%d)\n", BBS_max_section, errno); |
| 2161 |
|
} |
| 2162 |
|
} |
| 2163 |
|
|
| 2164 |
|
return 0; |
| 2165 |
|
} |
| 2166 |
|
#endif |