| 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]; |
| 1992 |
int timer = 0; |
int timer = 0; |
| 1993 |
int sid = (p_section == NULL ? 0 : p_section->sid); |
int sid = (p_section == NULL ? 0 : p_section->sid); |
| 1994 |
int ret = -1; |
int ret = -1; |
| 1995 |
|
time_t tm_first_failure = 0; |
| 1996 |
|
|
| 1997 |
while (!SYS_server_exit) |
while (!SYS_server_exit) |
| 1998 |
{ |
{ |
| 2003 |
} |
} |
| 2004 |
else if (errno == EAGAIN || errno == EINTR) // retry |
else if (errno == EAGAIN || errno == EINTR) // retry |
| 2005 |
{ |
{ |
| 2006 |
|
// Dead lock detection |
| 2007 |
|
if (tm_first_failure == 0) |
| 2008 |
|
{ |
| 2009 |
|
time(&tm_first_failure); |
| 2010 |
|
} |
| 2011 |
|
|
| 2012 |
timer++; |
timer++; |
| 2013 |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
| 2014 |
{ |
{ |
| 2015 |
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); |
| 2016 |
|
if (time(NULL) - tm_first_failure >= SECTION_DEAD_LOCK_TIMEOUT) |
| 2017 |
|
{ |
| 2018 |
|
log_error("Unable to acquire rd_lock for %d seconds\n", time(NULL) - tm_first_failure); |
| 2019 |
|
#ifndef HAVE_SYSTEM_V |
| 2020 |
|
section_list_reset_lock(p_section); |
| 2021 |
|
log_error("Reset POSIX semaphore to resolve dead lock\n"); |
| 2022 |
|
#endif |
| 2023 |
|
break; |
| 2024 |
|
} |
| 2025 |
} |
} |
| 2026 |
usleep(100 * 1000); // 0.1 second |
usleep(100 * 1000); // 0.1 second |
| 2027 |
} |
} |
| 2040 |
int timer = 0; |
int timer = 0; |
| 2041 |
int sid = (p_section == NULL ? 0 : p_section->sid); |
int sid = (p_section == NULL ? 0 : p_section->sid); |
| 2042 |
int ret = -1; |
int ret = -1; |
| 2043 |
|
time_t tm_first_failure = 0; |
| 2044 |
|
|
| 2045 |
while (!SYS_server_exit) |
while (!SYS_server_exit) |
| 2046 |
{ |
{ |
| 2051 |
} |
} |
| 2052 |
else if (errno == EAGAIN || errno == EINTR) // retry |
else if (errno == EAGAIN || errno == EINTR) // retry |
| 2053 |
{ |
{ |
| 2054 |
|
// Dead lock detection |
| 2055 |
|
if (tm_first_failure == 0) |
| 2056 |
|
{ |
| 2057 |
|
time(&tm_first_failure); |
| 2058 |
|
} |
| 2059 |
|
|
| 2060 |
timer++; |
timer++; |
| 2061 |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
if (timer % SECTION_TRY_LOCK_TIMES == 0) |
| 2062 |
{ |
{ |
| 2063 |
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); |
| 2064 |
|
if (time(NULL) - tm_first_failure >= SECTION_DEAD_LOCK_TIMEOUT) |
| 2065 |
|
{ |
| 2066 |
|
log_error("Unable to acquire rw_lock for %d seconds\n", time(NULL) - tm_first_failure); |
| 2067 |
|
#ifndef HAVE_SYSTEM_V |
| 2068 |
|
section_list_reset_lock(p_section); |
| 2069 |
|
log_error("Reset POSIX semaphore to resolve dead lock\n"); |
| 2070 |
|
#endif |
| 2071 |
|
break; |
| 2072 |
|
} |
| 2073 |
} |
} |
| 2074 |
usleep(100 * 1000); // 0.1 second |
usleep(100 * 1000); // 0.1 second |
| 2075 |
} |
} |
| 2082 |
|
|
| 2083 |
return ret; |
return ret; |
| 2084 |
} |
} |
| 2085 |
|
|
| 2086 |
|
#ifndef HAVE_SYSTEM_V |
| 2087 |
|
int section_list_reset_lock(SECTION_LIST *p_section) |
| 2088 |
|
{ |
| 2089 |
|
int index; |
| 2090 |
|
|
| 2091 |
|
if (p_section == NULL) |
| 2092 |
|
{ |
| 2093 |
|
log_error("NULL pointer error\n"); |
| 2094 |
|
return -1; |
| 2095 |
|
} |
| 2096 |
|
|
| 2097 |
|
index = get_section_index(p_section); |
| 2098 |
|
if (index < 0) |
| 2099 |
|
{ |
| 2100 |
|
return -2; |
| 2101 |
|
} |
| 2102 |
|
|
| 2103 |
|
if (sem_destroy(&(p_section_list_pool->sem[index])) == -1) |
| 2104 |
|
{ |
| 2105 |
|
log_error("sem_destroy(sem[%d]) error (%d)\n", index, errno); |
| 2106 |
|
} |
| 2107 |
|
|
| 2108 |
|
p_section_list_pool->read_lock_count[index] = 0; |
| 2109 |
|
p_section_list_pool->write_lock_count[index] = 0; |
| 2110 |
|
|
| 2111 |
|
if (sem_init(&(p_section_list_pool->sem[index]), 1, 1) == -1) |
| 2112 |
|
{ |
| 2113 |
|
log_error("sem_init(sem[%d]) error (%d)\n", index, errno); |
| 2114 |
|
} |
| 2115 |
|
|
| 2116 |
|
if (index != BBS_max_section) |
| 2117 |
|
{ |
| 2118 |
|
if (sem_destroy(&(p_section_list_pool->sem[BBS_max_section])) == -1) |
| 2119 |
|
{ |
| 2120 |
|
log_error("sem_destroy(sem[%d]) error (%d)\n", BBS_max_section, errno); |
| 2121 |
|
} |
| 2122 |
|
|
| 2123 |
|
p_section_list_pool->read_lock_count[BBS_max_section] = 0; |
| 2124 |
|
p_section_list_pool->write_lock_count[BBS_max_section] = 0; |
| 2125 |
|
|
| 2126 |
|
if (sem_init(&(p_section_list_pool->sem[BBS_max_section]), 1, 1) == -1) |
| 2127 |
|
{ |
| 2128 |
|
log_error("sem_init(sem[%d]) error (%d)\n", BBS_max_section, errno); |
| 2129 |
|
} |
| 2130 |
|
} |
| 2131 |
|
|
| 2132 |
|
return 0; |
| 2133 |
|
} |
| 2134 |
|
#endif |