mirror of
https://github.com/upa/mscp.git
synced 2026-02-14 09:14:47 +08:00
mscp_prepare() scans source paths in a thread.
This commit runs mscp_prepare() in a pthread. mscp copy threads run aysnchronously with mscp_prepare(). So, when mscp_prepare() has not finished yet (due to too many source files), we can start to copy files.
This commit is contained in:
43
src/path.c
43
src/path.c
@@ -30,46 +30,50 @@ static int get_page_mask(void)
|
||||
|
||||
|
||||
/* chunk pool operations */
|
||||
#define CHUNK_POOL_STATE_ADDING 0
|
||||
#define CHUNK_POOL_STATE_DONE 1
|
||||
#define CHUNK_POOL_STATE_FILLING 0
|
||||
#define CHUNK_POOL_STATE_FILLED 1
|
||||
|
||||
void chunk_pool_init(struct chunk_pool *cp)
|
||||
{
|
||||
memset(cp, 0, sizeof(*cp));
|
||||
INIT_LIST_HEAD(&cp->list);
|
||||
lock_init(&cp->lock);
|
||||
cp->state = CHUNK_POOL_STATE_ADDING;
|
||||
cp->state = CHUNK_POOL_STATE_FILLING;
|
||||
}
|
||||
|
||||
static void chunk_pool_add(struct chunk_pool *cp, struct chunk *c)
|
||||
{
|
||||
LOCK_ACQUIRE_THREAD(&cp->lock);
|
||||
list_add_tail(&c->list, &cp->list);
|
||||
cp->count += 1;
|
||||
LOCK_RELEASE_THREAD();
|
||||
}
|
||||
|
||||
void chunk_pool_done(struct chunk_pool *cp)
|
||||
void chunk_pool_set_filled(struct chunk_pool *cp)
|
||||
{
|
||||
cp->state = CHUNK_POOL_STATE_DONE;
|
||||
cp->state = CHUNK_POOL_STATE_FILLED;
|
||||
}
|
||||
|
||||
int chunk_pool_size(struct chunk_pool *cp)
|
||||
bool chunk_pool_is_filled(struct chunk_pool *cp)
|
||||
{
|
||||
int n;
|
||||
LOCK_ACQUIRE_THREAD(&cp->lock);
|
||||
n = list_count(&cp->list);
|
||||
LOCK_RELEASE_THREAD();
|
||||
return n;
|
||||
return (cp->state == CHUNK_POOL_STATE_FILLED);
|
||||
}
|
||||
|
||||
size_t chunk_pool_size(struct chunk_pool *cp)
|
||||
{
|
||||
return cp->count;
|
||||
}
|
||||
|
||||
|
||||
struct chunk *chunk_pool_pop(struct chunk_pool *cp)
|
||||
{
|
||||
struct list_head *first = cp->list.next;
|
||||
struct list_head *first;
|
||||
struct chunk *c = NULL;
|
||||
|
||||
LOCK_ACQUIRE_THREAD(&cp->lock);
|
||||
first = cp->list.next;
|
||||
if (list_empty(&cp->list)) {
|
||||
if (cp->state == CHUNK_POOL_STATE_ADDING)
|
||||
if (!chunk_pool_is_filled(cp))
|
||||
c = CHUNK_POP_WAIT;
|
||||
else
|
||||
c = NULL; /* no more chunks */
|
||||
@@ -283,15 +287,19 @@ static int walk_path_recursive(sftp_session sftp, const char *path,
|
||||
return -1;
|
||||
|
||||
for (e = mscp_readdir(d); !mdirent_is_null(e); e = mscp_readdir(d)) {
|
||||
if (check_path_should_skip(mdirent_name(e)))
|
||||
if (check_path_should_skip(mdirent_name(e))) {
|
||||
mscp_dirent_free(e);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen(path) + 1 + strlen(mdirent_name(e)) > PATH_MAX) {
|
||||
mscp_set_error("too long path: %s/%s", path, mdirent_name(e));
|
||||
mscp_dirent_free(e);
|
||||
return -1;
|
||||
}
|
||||
snprintf(next_path, sizeof(next_path), "%s/%s", path, mdirent_name(e));
|
||||
ret = walk_path_recursive(sftp, next_path, path_list, a);
|
||||
mscp_dirent_free(e);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
@@ -339,10 +347,13 @@ static int touch_dst_path(struct path *p, sftp_session sftp)
|
||||
|
||||
mstat s;
|
||||
if (mscp_stat(path, &s, sftp) == 0) {
|
||||
if (mstat_is_dir(s))
|
||||
if (mstat_is_dir(s)) {
|
||||
mscp_stat_free(s);
|
||||
goto next; /* directory exists. go deeper */
|
||||
else
|
||||
} else {
|
||||
mscp_stat_free(s);
|
||||
return -1; /* path exists, but not directory. */
|
||||
}
|
||||
}
|
||||
|
||||
if (mscp_stat_check_err_noent(sftp) == 0) {
|
||||
|
||||
Reference in New Issue
Block a user