Commit 2b47832a authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru Committed by Vicențiu Ciorbaru

Fixed compilation failure using clang

Both aria and myisam storage engines feature a logic path in
thr_find_all_keys that leads to undefined behaviour by bypassing the
initialization code of variables after my_thread_init().

By refactoring the nested logic into a separate function, this problem
is resolved.
parent 6a34ba31
...@@ -330,7 +330,8 @@ typedef struct st_sort_info ...@@ -330,7 +330,8 @@ typedef struct st_sort_info
my_off_t filelength, dupp, buff_length; my_off_t filelength, dupp, buff_length;
ha_rows max_records; ha_rows max_records;
uint current_key, total_keys; uint current_key, total_keys;
uint got_error, threads_running; volatile uint got_error;
uint threads_running;
myf myf_rw; myf myf_rw;
enum data_file_type new_data_file_type; enum data_file_type new_data_file_type;
} MI_SORT_INFO; } MI_SORT_INFO;
......
...@@ -333,170 +333,187 @@ err: ...@@ -333,170 +333,187 @@ err:
} /* find_all_keys */ } /* find_all_keys */
/* Search after all keys and place them in a temp. file */ static my_bool _ma_thr_find_all_keys_exec(MARIA_SORT_PARAM* sort_param)
pthread_handler_t _ma_thr_find_all_keys(void *arg)
{ {
MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg; DBUG_ENTER("_ma_thr_find_all_keys");
int error; DBUG_PRINT("enter", ("master: %d", sort_param->master));
size_t memavl,old_memavl;
uint sort_length;
ulong idx, maxbuffer, keys;
uchar **sort_keys=0;
LINT_INIT(keys);
error=1; my_bool error= FALSE;
ulonglong memavl, old_memavl;
uint UNINIT_VAR(keys), idx;
uint sort_length;
uint maxbuffer;
uchar **sort_keys= NULL;
if (my_thread_init()) if (sort_param->sort_info->got_error)
goto err; DBUG_RETURN(TRUE);
{ /* Add extra block since DBUG_ENTER declare variables */ set_sort_param_read_write(sort_param);
DBUG_ENTER("_ma_thr_find_all_keys");
DBUG_PRINT("enter", ("master: %d", sort_param->master));
if (sort_param->sort_info->got_error)
goto err;
set_sort_param_read_write(sort_param);
my_b_clear(&sort_param->tempfile); my_b_clear(&sort_param->tempfile);
my_b_clear(&sort_param->tempfile_for_exceptions); my_b_clear(&sort_param->tempfile_for_exceptions);
bzero((char*) &sort_param->buffpek,sizeof(sort_param->buffpek)); bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY);
idx= (uint)sort_param->sort_info->max_records; idx= sort_param->sort_info->max_records;
sort_length= sort_param->key_length; sort_length= sort_param->key_length;
maxbuffer= 1; maxbuffer= 1;
while (memavl >= MIN_SORT_MEMORY) while (memavl >= MIN_SORT_MEMORY)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl)
keys= idx+1;
else
{ {
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= (my_off_t) memavl) ulong skr;
keys= idx+1; do
else
{
ulong skr;
do
{
skr= maxbuffer;
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
keys < maxbuffer)
{
_ma_check_print_error(sort_param->sort_info->param,
"aria_sort_buffer_size is too small");
goto err;
}
}
while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
}
if ((sort_keys= (uchar **)
my_malloc(keys*(sort_length+sizeof(char*))+
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
HA_FT_MAXBYTELEN : 0), MYF(0))))
{ {
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), skr= maxbuffer;
maxbuffer, maxbuffer/2)) if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
keys < maxbuffer)
{ {
my_free(sort_keys); _ma_check_print_error(sort_param->sort_info->param,
sort_keys= (uchar **) NULL; /* for err: label */ "aria_sort_buffer_size is too small");
goto err;
} }
else
break;
} }
old_memavl= memavl; while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
old_memavl > MIN_SORT_MEMORY)
memavl= MIN_SORT_MEMORY;
} }
if (memavl < MIN_SORT_MEMORY) if ((sort_keys= (uchar **)
my_malloc(keys*(sort_length+sizeof(char*))+
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
HA_FT_MAXBYTELEN : 0), MYF(0))))
{ {
_ma_check_print_error(sort_param->sort_info->param, if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
"Aria sort buffer too small"); maxbuffer, maxbuffer / 2))
goto err; /* purecov: tested */ {
my_free(sort_keys);
sort_keys= NULL; /* Safety against double free on error. */
}
else
break;
} }
old_memavl= memavl;
if ((memavl= memavl/4*3) < MIN_SORT_MEMORY &&
old_memavl > MIN_SORT_MEMORY)
memavl= MIN_SORT_MEMORY;
}
if (sort_param->sort_info->param->testflag & T_VERBOSE) if (memavl < MIN_SORT_MEMORY)
printf("Key %d - Allocating buffer for %lu keys\n", {
sort_param->key+1, (ulong) keys); /* purecov: begin inspected */
sort_param->sort_keys= sort_keys; _ma_check_print_error(sort_param->sort_info->param,
"aria_sort_buffer_size is too small. Current "
"aria_sort_buffer_size: %llu rows: %llu "
"sort_length: %u",
(ulonglong) sort_param->sortbuff_size,
(ulonglong) idx, sort_length);
my_errno= ENOMEM;
goto err;
/* purecov: end inspected */
}
idx= error= 0; if (sort_param->sort_info->param->testflag & T_VERBOSE)
sort_keys[0]= (uchar*) (sort_keys+keys); printf("Key %d - Allocating buffer for %llu keys\n",
sort_param->key + 1, (ulonglong) keys);
sort_param->sort_keys= sort_keys;
DBUG_PRINT("info", ("reading keys")); idx= error= 0;
while (!(error= sort_param->sort_info->got_error) && sort_keys[0]= (uchar*) (sort_keys+keys);
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
{
if (sort_param->real_key_length > sort_param->key_length)
{
if (write_key(sort_param,sort_keys[idx],
&sort_param->tempfile_for_exceptions))
goto err;
continue;
}
if (++idx == keys) DBUG_PRINT("info", ("reading keys"));
{ while (!(error= sort_param->sort_info->got_error) &&
if (sort_param->write_keys(sort_param, sort_keys, idx - 1, !(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
(BUFFPEK *)alloc_dynamic(&sort_param-> {
buffpek), if (sort_param->real_key_length > sort_param->key_length)
&sort_param->tempfile)) {
goto err; if (write_key(sort_param, sort_keys[idx],
sort_keys[0]= (uchar*) (sort_keys+keys); &sort_param->tempfile_for_exceptions))
memcpy(sort_keys[0], sort_keys[idx - 1], goto err;
(size_t) sort_param->key_length); continue;
idx= 1;
}
sort_keys[idx]=sort_keys[idx - 1] + sort_param->key_length;
} }
if (error > 0)
goto err; if (++idx == keys)
if (sort_param->buffpek.elements)
{ {
if (sort_param->write_keys(sort_param,sort_keys, idx, if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
(BUFFPEK *) alloc_dynamic(&sort_param-> (BUFFPEK *)alloc_dynamic(&sort_param->buffpek),
buffpek),
&sort_param->tempfile)) &sort_param->tempfile))
goto err; goto err;
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; sort_keys[0]= (uchar*) (sort_keys+keys);
memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
idx= 1;
} }
else sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
sort_param->keys= idx; }
if (error > 0)
goto err;
if (sort_param->buffpek.elements)
{
if (sort_param->write_keys(sort_param,sort_keys, idx,
(BUFFPEK *) alloc_dynamic(&sort_param->buffpek),
&sort_param->tempfile))
goto err;
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
}
else
sort_param->keys= idx;
sort_param->sort_keys_length= keys; sort_param->sort_keys_length= keys;
goto ok; DBUG_RETURN(FALSE);
err: err:
DBUG_PRINT("error", ("got some error")); DBUG_PRINT("error", ("got some error"));
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ my_free(sort_keys);
my_free(sort_keys); sort_param->sort_keys= 0;
sort_param->sort_keys=0; delete_dynamic(& sort_param->buffpek);
delete_dynamic(& sort_param->buffpek); close_cached_file(&sort_param->tempfile);
close_cached_file(&sort_param->tempfile); close_cached_file(&sort_param->tempfile_for_exceptions);
close_cached_file(&sort_param->tempfile_for_exceptions);
DBUG_RETURN(TRUE);
ok: }
free_root(&sort_param->wordroot, MYF(0));
/* /* Search after all keys and place them in a temp. file */
Detach from the share if the writer is involved. Avoid others to
be blocked. This includes a flush of the write buffer. This will pthread_handler_t _ma_thr_find_all_keys(void *arg)
also indicate EOF to the readers. {
*/ MARIA_SORT_PARAM *sort_param= (MARIA_SORT_PARAM*) arg;
if (sort_param->sort_info->info->rec_cache.share) my_bool error= FALSE;
remove_io_thread(&sort_param->sort_info->info->rec_cache); /* If my_thread_init fails */
if (my_thread_init() || _ma_thr_find_all_keys_exec(sort_param))
/* Readers detach from the share if any. Avoid others to be blocked. */ error= TRUE;
if (sort_param->read_cache.share)
remove_io_thread(&sort_param->read_cache); /*
Thread must clean up after itself.
mysql_mutex_lock(&sort_param->sort_info->mutex); */
if (!--sort_param->sort_info->threads_running) free_root(&sort_param->wordroot, MYF(0));
mysql_cond_signal(&sort_param->sort_info->cond); /*
mysql_mutex_unlock(&sort_param->sort_info->mutex); Detach from the share if the writer is involved. Avoid others to
DBUG_PRINT("exit", ("======== ending thread ========")); be blocked. This includes a flush of the write buffer. This will
} also indicate EOF to the readers.
That means that a writer always gets here first and readers -
only when they see EOF. But if a reader finishes prematurely
because of an error it may reach this earlier - don't allow it
to detach the writer thread.
*/
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */
if (sort_param->read_cache.share)
remove_io_thread(&sort_param->read_cache);
mysql_mutex_lock(&sort_param->sort_info->mutex);
if (error)
sort_param->sort_info->got_error= 1;
if (!--sort_param->sort_info->threads_running)
mysql_cond_signal(&sort_param->sort_info->cond);
mysql_mutex_unlock(&sort_param->sort_info->mutex);
my_thread_end(); my_thread_end();
return NULL; return NULL;
} }
......
...@@ -67,7 +67,8 @@ typedef struct st_maria_sort_info ...@@ -67,7 +67,8 @@ typedef struct st_maria_sort_info
pgcache_page_no_t page; pgcache_page_no_t page;
ha_rows max_records; ha_rows max_records;
uint current_key, total_keys; uint current_key, total_keys;
uint got_error, threads_running; volatile uint got_error;
uint threads_running;
myf myf_rw; myf myf_rw;
enum data_file_type new_data_file_type, org_data_file_type; enum data_file_type new_data_file_type, org_data_file_type;
} MARIA_SORT_INFO; } MARIA_SORT_INFO;
......
...@@ -318,177 +318,194 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys, ...@@ -318,177 +318,194 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys,
DBUG_RETURN((*maxbuffer)*(keys-1)+idx); DBUG_RETURN((*maxbuffer)*(keys-1)+idx);
} /* find_all_keys */ } /* find_all_keys */
/* Search after all keys and place them in a temp. file */ static my_bool thr_find_all_keys_exec(MI_SORT_PARAM *sort_param)
pthread_handler_t thr_find_all_keys(void *arg)
{ {
MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg; DBUG_ENTER("thr_find_all_keys");
int error; DBUG_PRINT("enter", ("master: %d", sort_param->master));
ulonglong memavl, old_memavl;
uint keys, sort_length;
uint idx, maxbuffer;
uchar **sort_keys=0;
LINT_INIT(keys);
error=1; ulonglong memavl, old_memavl;
uint UNINIT_VAR(keys), idx;
if (my_thread_init()) uint sort_length;
goto err; uint maxbuffer;
uchar **sort_keys= NULL;
{ /* Add extra block since DBUG_ENTER declare variables */
DBUG_ENTER("thr_find_all_keys"); my_bool error= FALSE;
DBUG_PRINT("enter", ("master: %d", sort_param->master)); if (sort_param->sort_info->got_error)
if (sort_param->sort_info->got_error) error= TRUE;
goto err; if (error)
DBUG_RETURN(error);
set_sort_param_read_write(sort_param);
set_sort_param_read_write(sort_param);
my_b_clear(&sort_param->tempfile);
my_b_clear(&sort_param->tempfile_for_exceptions); my_b_clear(&sort_param->tempfile);
bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); my_b_clear(&sort_param->tempfile_for_exceptions);
bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek));
sort_keys= (uchar **) NULL; bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER); memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
idx= (uint)sort_param->sort_info->max_records; idx= (uint) sort_param->sort_info->max_records;
sort_length= sort_param->key_length; sort_length= sort_param->key_length;
maxbuffer= 1; maxbuffer= 1;
if ((memavl - sizeof(BUFFPEK)) / (sort_length + if ((memavl - sizeof(BUFFPEK)) / (sort_length +
sizeof(char *)) > UINT_MAX32) sizeof(char *)) > UINT_MAX32)
memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *)); memavl= sizeof(BUFFPEK) + UINT_MAX32 * (sort_length + sizeof(char *));
while (memavl >= MIN_SORT_BUFFER) while (memavl >= MIN_SORT_BUFFER)
{
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <=
(my_off_t) memavl)
keys= idx+1;
else
{ {
if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= uint skr;
(my_off_t) memavl) do
keys= idx+1;
else
{
uint skr;
do
{
skr= maxbuffer;
if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
keys < (uint) maxbuffer)
{
mi_check_print_error(sort_param->sort_info->param,
"myisam_sort_buffer_size is too small");
goto err;
}
}
while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
}
if ((sort_keys= (uchar**)
my_malloc(keys*(sort_length+sizeof(char*))+
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
HA_FT_MAXBYTELEN : 0), MYF(0))))
{ {
if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), skr= maxbuffer;
maxbuffer, maxbuffer/2)) if (memavl < sizeof(BUFFPEK)*maxbuffer ||
(keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/
(sort_length+sizeof(char*))) <= 1 ||
keys < (uint) maxbuffer)
{ {
my_free(sort_keys); mi_check_print_error(sort_param->sort_info->param,
sort_keys= (uchar **) NULL; /* for err: label */ "myisam_sort_buffer_size is too small. Current "
"myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
sort_param->sortbuff_size, (ulonglong) idx, sort_length);
DBUG_RETURN(TRUE);
} }
else
break;
} }
old_memavl= memavl; while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr);
if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER &&
old_memavl > MIN_SORT_BUFFER)
memavl= MIN_SORT_BUFFER;
} }
if (memavl < MIN_SORT_BUFFER) if ((sort_keys= my_malloc(keys * (sort_length + sizeof(char *)) +
((sort_param->keyinfo->flag & HA_FULLTEXT) ?
HA_FT_MAXBYTELEN : 0), MYF(0))))
{ {
mi_check_print_error(sort_param->sort_info->param, if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK),
"MyISAM sort buffer too small"); maxbuffer, min(maxbuffer / 2, 1000)))
goto err; /* purecov: tested */ {
my_free(sort_keys);
sort_keys= NULL; /* Safety against double free on error. */
}
else
break;
} }
old_memavl= memavl;
if ((memavl= memavl / 4 * 3) < MIN_SORT_BUFFER &&
old_memavl > MIN_SORT_BUFFER)
memavl= MIN_SORT_BUFFER;
}
if (memavl < MIN_SORT_BUFFER)
{
/* purecov: begin inspected */
mi_check_print_error(sort_param->sort_info->param,
"myisam_sort_buffer_size is too small. Current "
"myisam_sort_buffer_size: %llu rows: %llu sort_length: %u",
sort_param->sortbuff_size, (ulonglong) idx, sort_length);
my_errno= ENOMEM;
goto err;
/* purecov: end inspected */
}
if (sort_param->sort_info->param->testflag & T_VERBOSE) if (sort_param->sort_info->param->testflag & T_VERBOSE)
printf("Key %d - Allocating buffer for %d keys\n", printf("Key %d - Allocating buffer for %llu keys\n",
sort_param->key + 1, keys); sort_param->key + 1, (ulonglong) keys);
sort_param->sort_keys= sort_keys; sort_param->sort_keys= sort_keys;
idx= error= 0; idx= error= 0;
sort_keys[0]= (uchar*) (sort_keys+keys); sort_keys[0]= (uchar*) (sort_keys+keys);
DBUG_PRINT("info", ("reading keys")); DBUG_PRINT("info", ("reading keys"));
while (!(error= sort_param->sort_info->got_error) && while (!(error= sort_param->sort_info->got_error) &&
!(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) !(error= (*sort_param->key_read)(sort_param, sort_keys[idx])))
{
if (sort_param->real_key_length > sort_param->key_length)
{ {
if (sort_param->real_key_length > sort_param->key_length) if (write_key(sort_param, sort_keys[idx],
{ &sort_param->tempfile_for_exceptions))
if (write_key(sort_param, sort_keys[idx], goto err;
&sort_param->tempfile_for_exceptions)) continue;
goto err;
continue;
}
if (++idx == keys)
{
if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
&sort_param->tempfile))
goto err;
sort_keys[0]= (uchar*) (sort_keys+keys);
memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
idx= 1;
}
sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
} }
if (error > 0)
goto err; if (++idx == keys)
if (sort_param->buffpek.elements)
{ {
if (sort_param->write_keys(sort_param, sort_keys, idx, if (sort_param->write_keys(sort_param, sort_keys, idx - 1,
(BUFFPEK*) alloc_dynamic(&sort_param->buffpek), (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
&sort_param->tempfile)) &sort_param->tempfile))
goto err; goto err;
sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; sort_keys[0]= (uchar*) (sort_keys+keys);
memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length);
idx= 1;
} }
else sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length;
sort_param->keys= idx; }
sort_param->sort_keys_length= keys; if (error > 0)
goto ok; goto err;
err: if (sort_param->buffpek.elements)
DBUG_PRINT("error", ("got some error")); {
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ if (sort_param->write_keys(sort_param, sort_keys, idx,
my_free(sort_keys); (BUFFPEK*) alloc_dynamic(&sort_param->buffpek),
sort_param->sort_keys= 0; &sort_param->tempfile))
delete_dynamic(& sort_param->buffpek); goto err;
close_cached_file(&sort_param->tempfile); sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx;
close_cached_file(&sort_param->tempfile_for_exceptions);
ok:
free_root(&sort_param->wordroot, MYF(0));
/*
Detach from the share if the writer is involved. Avoid others to
be blocked. This includes a flush of the write buffer. This will
also indicate EOF to the readers.
That means that a writer always gets here first and readers -
only when they see EOF. But if a reader finishes prematurely
because of an error it may reach this earlier - don't allow it
to detach the writer thread.
*/
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */
if (sort_param->read_cache.share)
remove_io_thread(&sort_param->read_cache);
mysql_mutex_lock(&sort_param->sort_info->mutex);
if (!--sort_param->sort_info->threads_running)
mysql_cond_signal(&sort_param->sort_info->cond);
mysql_mutex_unlock(&sort_param->sort_info->mutex);
DBUG_PRINT("exit", ("======== ending thread ========"));
} }
else
sort_param->keys= idx;
sort_param->sort_keys_length= keys;
DBUG_RETURN(FALSE);
err:
DBUG_PRINT("error", ("got some error"));
sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */
my_free(sort_keys);
sort_param->sort_keys= 0;
delete_dynamic(& sort_param->buffpek);
close_cached_file(&sort_param->tempfile);
close_cached_file(&sort_param->tempfile_for_exceptions);
DBUG_RETURN(TRUE);
}
/* Search after all keys and place them in a temp. file */
pthread_handler_t thr_find_all_keys(void *arg)
{
MI_SORT_PARAM *sort_param= (MI_SORT_PARAM*) arg;
my_bool error= FALSE;
/* If my_thread_init fails */
if (my_thread_init() || thr_find_all_keys_exec(sort_param))
error= TRUE;
/*
Thread must clean up after itself.
*/
free_root(&sort_param->wordroot, MYF(0));
/*
Detach from the share if the writer is involved. Avoid others to
be blocked. This includes a flush of the write buffer. This will
also indicate EOF to the readers.
That means that a writer always gets here first and readers -
only when they see EOF. But if a reader finishes prematurely
because of an error it may reach this earlier - don't allow it
to detach the writer thread.
*/
if (sort_param->master && sort_param->sort_info->info->rec_cache.share)
remove_io_thread(&sort_param->sort_info->info->rec_cache);
/* Readers detach from the share if any. Avoid others to be blocked. */
if (sort_param->read_cache.share)
remove_io_thread(&sort_param->read_cache);
mysql_mutex_lock(&sort_param->sort_info->mutex);
if (error)
sort_param->sort_info->got_error= 1;
if (!--sort_param->sort_info->threads_running)
mysql_cond_signal(&sort_param->sort_info->cond);
mysql_mutex_unlock(&sort_param->sort_info->mutex);
my_thread_end(); my_thread_end();
return NULL; return NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment