Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 33 additions & 20 deletions src/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* \details This allows LinkTable generation to be run exclusively. This
* effectively gives LinkTable generation priority over file transfer.
*/
static pthread_mutex_t link_lock;
static pthread_rwlock_t link_lock;
static void make_link_relative(const char *page_url, char *link_url);

/**
Expand Down Expand Up @@ -286,7 +286,7 @@

LinkTable *LinkSystem_init(const char *url)
{
PTHREAD_MUTEX_INIT(&link_lock, NULL);
pthread_rwlock_init(&link_lock, NULL);
int url_len = strnlen(url, MAX_PATH_LEN) - 1;
/*
* --------- Set the length of the root link -----------
Expand Down Expand Up @@ -845,93 +845,106 @@
return next_table;
}

static Link *path_to_Link_recursive(char *path, LinkTable *linktbl)
{
/*
* skip the leading '/' if it exists
*/
if (*path == '/') {
path++;
}

/*
* remove the last '/' if it exists
*/
char *slash = &(path[strnlen(path, MAX_PATH_LEN) - 1]);
if (*slash == '/') {
*slash = '\0';
}

slash = strchr(path, '/');
if (slash == NULL) {
/*
* We cannot find another '/', we have reached the last level
*/
for (int i = 1; i < linktbl->num; i++) {
if (!strncmp
(path, linktbl->links[i]->linkname, MAX_FILENAME_LEN)) {
/*
* We found our link
*/
return linktbl->links[i];
}
}
} else {
/*
* We can still find '/', time to consume the path and traverse
* the tree structure
*/

/*
* add termination mark to the current string,
* effective create two substrings
*/
*slash = '\0';
/*
* move the pointer past the '/'
*/
char *next_path = slash + 1;
for (int i = 1; i < linktbl->num; i++) {
if (!strncmp
(path, linktbl->links[i]->linkname, MAX_FILENAME_LEN)) {
/*
* The next sub-directory exists
*/
LinkTable *next_table = linktbl->links[i]->next_table;
if (!next_table) {
if (CONFIG.mode == NORMAL) {
next_table =
LinkTable_new(linktbl->links[i]->f_url);
} else if (CONFIG.mode == SONIC) {
if (!CONFIG.sonic_id3) {
pthread_rwlock_unlock(&link_lock);
pthread_rwlock_wrlock(&link_lock);
next_table = linktbl->links[i]->next_table;

if (!next_table) {
if (CONFIG.mode == NORMAL) {
next_table =
sonic_LinkTable_new_index
(linktbl->links[i]->sonic.id);
LinkTable_new(linktbl->links[i]->f_url);
} else if (CONFIG.mode == SONIC) {
if (!CONFIG.sonic_id3) {
next_table =
sonic_LinkTable_new_index
(linktbl->links[i]->sonic.id);
} else {
next_table =
sonic_LinkTable_new_id3
(linktbl->links
[i]->sonic.depth,
linktbl->links[i]->sonic.id);
}
} else {
next_table =
sonic_LinkTable_new_id3
(linktbl->links
[i]->sonic.depth,
linktbl->links[i]->sonic.id);
lprintf(fatal, "Invalid CONFIG.mode\n");
}
} else {
lprintf(fatal, "Invalid CONFIG.mode\n");
linktbl->links[i]->next_table = next_table;
}
pthread_rwlock_unlock(&link_lock);
pthread_rwlock_rdlock(&link_lock);
next_table = linktbl->links[i]->next_table;
}
if (next_table) {
return path_to_Link_recursive(next_path, next_table);
} else {
return NULL;
}
linktbl->links[i]->next_table = next_table;
return path_to_Link_recursive(next_path, next_table);
}
}
}
return NULL;
}

Check notice on line 941 in src/link.c

View check run for this annotation

codefactor.io / CodeFactor

src/link.c#L848-L941

Complex Method
Link *path_to_Link(const char *path)
{
lprintf(link_lock_debug,
"thread %x: locking link_lock;\n", pthread_self());

PTHREAD_MUTEX_LOCK(&link_lock);
pthread_rwlock_rdlock(&link_lock);
char *new_path = strndup(path, MAX_PATH_LEN);
if (!new_path) {
lprintf(fatal, "cannot allocate memory\n");
Expand All @@ -941,7 +954,7 @@

lprintf(link_lock_debug,
"thread %x: unlocking link_lock;\n", pthread_self());
PTHREAD_MUTEX_UNLOCK(&link_lock);
pthread_rwlock_unlock(&link_lock);
return link;
}

Expand Down
Loading