mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-12-11 22:24:42 +00:00
Read input scripts which look like input objects with proper
serialization.
This commit is contained in:
parent
a7dfd0102b
commit
da769d5629
147
gold/readsyms.cc
147
gold/readsyms.cc
@ -120,8 +120,8 @@ Read_symbols::run(Workqueue* workqueue)
|
|||||||
// If we didn't queue a new task, then we need to explicitly unblock
|
// If we didn't queue a new task, then we need to explicitly unblock
|
||||||
// the token.
|
// the token.
|
||||||
if (!this->do_read_symbols(workqueue))
|
if (!this->do_read_symbols(workqueue))
|
||||||
workqueue->queue_front(new Unblock_token(this->this_blocker_,
|
workqueue->queue_soon(new Unblock_token(this->this_blocker_,
|
||||||
this->next_blocker_));
|
this->next_blocker_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the file and read the symbols. Return true if a new task was
|
// Open the file and read the symbols. Return true if a new task was
|
||||||
@ -189,11 +189,14 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
|||||||
|
|
||||||
input_file->file().unlock(this);
|
input_file->file().unlock(this);
|
||||||
|
|
||||||
workqueue->queue_front(new Add_symbols(this->input_objects_,
|
// We use queue_next because everything is cached for this
|
||||||
this->symtab_, this->layout_,
|
// task to run right away if possible.
|
||||||
obj, sd,
|
|
||||||
this->this_blocker_,
|
workqueue->queue_next(new Add_symbols(this->input_objects_,
|
||||||
this->next_blocker_));
|
this->symtab_, this->layout_,
|
||||||
|
obj, sd,
|
||||||
|
this->this_blocker_,
|
||||||
|
this->next_blocker_));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -208,30 +211,34 @@ Read_symbols::do_read_symbols(Workqueue* workqueue)
|
|||||||
input_file);
|
input_file);
|
||||||
arch->setup(this);
|
arch->setup(this);
|
||||||
|
|
||||||
workqueue->queue_front(new Add_archive_symbols(this->symtab_,
|
workqueue->queue_next(new Add_archive_symbols(this->symtab_,
|
||||||
this->layout_,
|
this->layout_,
|
||||||
this->input_objects_,
|
this->input_objects_,
|
||||||
arch,
|
arch,
|
||||||
this->input_group_,
|
this->input_group_,
|
||||||
this->this_blocker_,
|
this->this_blocker_,
|
||||||
this->next_blocker_));
|
this->next_blocker_));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to parse this file as a script.
|
// Queue up a task to try to parse this file as a script. We use a
|
||||||
if (read_input_script(workqueue, this->options_, this->symtab_,
|
// separate task so that the script will be read in order with other
|
||||||
this->layout_, this->dirpath_, this->input_objects_,
|
// objects named on the command line. Also so that we don't try to
|
||||||
this->input_group_, this->input_argument_, input_file,
|
// read multiple scripts simultaneously, which could lead to
|
||||||
ehdr_buf, read_size, this->this_blocker_,
|
// unpredictable changes to the General_options structure.
|
||||||
this->next_blocker_))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// Here we have to handle any other input file types we need.
|
workqueue->queue_soon(new Read_script(this->options_,
|
||||||
gold_error(_("%s: not an object or archive"),
|
this->symtab_,
|
||||||
input_file->file().filename().c_str());
|
this->layout_,
|
||||||
|
this->dirpath_,
|
||||||
return false;
|
this->input_objects_,
|
||||||
|
this->input_group_,
|
||||||
|
this->input_argument_,
|
||||||
|
input_file,
|
||||||
|
this->this_blocker_,
|
||||||
|
this->next_blocker_));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle a group. We need to walk through the arguments over and
|
// Handle a group. We need to walk through the arguments over and
|
||||||
@ -258,21 +265,22 @@ Read_symbols::do_group(Workqueue* workqueue)
|
|||||||
|
|
||||||
Task_token* next_blocker = new Task_token(true);
|
Task_token* next_blocker = new Task_token(true);
|
||||||
next_blocker->add_blocker();
|
next_blocker->add_blocker();
|
||||||
workqueue->queue(new Read_symbols(this->options_, this->input_objects_,
|
workqueue->queue_soon(new Read_symbols(this->options_,
|
||||||
this->symtab_, this->layout_,
|
this->input_objects_,
|
||||||
this->dirpath_, arg, input_group,
|
this->symtab_, this->layout_,
|
||||||
this_blocker, next_blocker));
|
this->dirpath_, arg, input_group,
|
||||||
|
this_blocker, next_blocker));
|
||||||
this_blocker = next_blocker;
|
this_blocker = next_blocker;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int saw_undefined = this->symtab_->saw_undefined();
|
const int saw_undefined = this->symtab_->saw_undefined();
|
||||||
workqueue->queue(new Finish_group(this->input_objects_,
|
workqueue->queue_soon(new Finish_group(this->input_objects_,
|
||||||
this->symtab_,
|
this->symtab_,
|
||||||
this->layout_,
|
this->layout_,
|
||||||
input_group,
|
input_group,
|
||||||
saw_undefined,
|
saw_undefined,
|
||||||
this_blocker,
|
this_blocker,
|
||||||
this->next_blocker_));
|
this->next_blocker_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a debugging name for a Read_symbols task.
|
// Return a debugging name for a Read_symbols task.
|
||||||
@ -409,4 +417,69 @@ Finish_group::run(Workqueue*)
|
|||||||
delete this->input_group_;
|
delete this->input_group_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Class Read_script
|
||||||
|
|
||||||
|
Read_script::~Read_script()
|
||||||
|
{
|
||||||
|
if (this->this_blocker_ != NULL)
|
||||||
|
delete this->this_blocker_;
|
||||||
|
// next_blocker_ is deleted by the task associated with the next
|
||||||
|
// input file.
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are blocked by this_blocker_.
|
||||||
|
|
||||||
|
Task_token*
|
||||||
|
Read_script::is_runnable()
|
||||||
|
{
|
||||||
|
if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
|
||||||
|
return this->this_blocker_;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't unlock next_blocker_ here. If the script names any input
|
||||||
|
// files, then the last file will be responsible for unlocking it.
|
||||||
|
|
||||||
|
void
|
||||||
|
Read_script::locks(Task_locker*)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the script, if it is a script.
|
||||||
|
|
||||||
|
void
|
||||||
|
Read_script::run(Workqueue* workqueue)
|
||||||
|
{
|
||||||
|
bool used_next_blocker;
|
||||||
|
if (!read_input_script(workqueue, this->options_, this->symtab_,
|
||||||
|
this->layout_, this->dirpath_, this->input_objects_,
|
||||||
|
this->input_group_, this->input_argument_,
|
||||||
|
this->input_file_, this->next_blocker_,
|
||||||
|
&used_next_blocker))
|
||||||
|
{
|
||||||
|
// Here we have to handle any other input file types we need.
|
||||||
|
gold_error(_("%s: not an object or archive"),
|
||||||
|
this->input_file_->file().filename().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!used_next_blocker)
|
||||||
|
{
|
||||||
|
// Queue up a task to unlock next_blocker. We can't just unlock
|
||||||
|
// it here, as we don't hold the workqueue lock.
|
||||||
|
workqueue->queue_soon(new Unblock_token(NULL, this->next_blocker_));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return a debugging name for a Read_script task.
|
||||||
|
|
||||||
|
std::string
|
||||||
|
Read_script::get_name() const
|
||||||
|
{
|
||||||
|
std::string ret("Read_script ");
|
||||||
|
if (this->input_argument_->file().is_lib())
|
||||||
|
ret += "-l";
|
||||||
|
ret += this->input_argument_->file().name();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
} // End namespace gold.
|
} // End namespace gold.
|
||||||
|
@ -220,6 +220,53 @@ class Finish_group : public Task
|
|||||||
Task_token* next_blocker_;
|
Task_token* next_blocker_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// This class is used to read a file which was not recognized as an
|
||||||
|
// object or archive. It tries to read it as a linker script, using
|
||||||
|
// the tokens to serialize with the calls to Add_symbols.
|
||||||
|
|
||||||
|
class Read_script : public Task
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Read_script(const General_options& options, Symbol_table* symtab,
|
||||||
|
Layout* layout, Dirsearch* dirpath, Input_objects* input_objects,
|
||||||
|
Input_group* input_group, const Input_argument* input_argument,
|
||||||
|
Input_file* input_file, Task_token* this_blocker,
|
||||||
|
Task_token* next_blocker)
|
||||||
|
: options_(options), symtab_(symtab), layout_(layout), dirpath_(dirpath),
|
||||||
|
input_objects_(input_objects), input_group_(input_group),
|
||||||
|
input_argument_(input_argument), input_file_(input_file),
|
||||||
|
this_blocker_(this_blocker), next_blocker_(next_blocker)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
~Read_script();
|
||||||
|
|
||||||
|
// The standard Task methods.
|
||||||
|
|
||||||
|
Task_token*
|
||||||
|
is_runnable();
|
||||||
|
|
||||||
|
void
|
||||||
|
locks(Task_locker*);
|
||||||
|
|
||||||
|
void
|
||||||
|
run(Workqueue*);
|
||||||
|
|
||||||
|
std::string
|
||||||
|
get_name() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const General_options& options_;
|
||||||
|
Symbol_table* symtab_;
|
||||||
|
Layout* layout_;
|
||||||
|
Dirsearch* dirpath_;
|
||||||
|
Input_objects* input_objects_;
|
||||||
|
Input_group* input_group_;
|
||||||
|
const Input_argument* input_argument_;
|
||||||
|
Input_file* input_file_;
|
||||||
|
Task_token* this_blocker_;
|
||||||
|
Task_token* next_blocker_;
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace gold
|
} // end namespace gold
|
||||||
|
|
||||||
#endif // !defined(GOLD_READSYMS_H)
|
#endif // !defined(GOLD_READSYMS_H)
|
||||||
|
@ -64,9 +64,9 @@ Read_relocs::run(Workqueue* workqueue)
|
|||||||
this->object_->read_relocs(rd);
|
this->object_->read_relocs(rd);
|
||||||
this->object_->release();
|
this->object_->release();
|
||||||
|
|
||||||
workqueue->queue_front(new Scan_relocs(this->options_, this->symtab_,
|
workqueue->queue_next(new Scan_relocs(this->options_, this->symtab_,
|
||||||
this->layout_, this->object_, rd,
|
this->layout_, this->object_, rd,
|
||||||
this->symtab_lock_, this->blocker_));
|
this->symtab_lock_, this->blocker_));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return a debugging name for the task.
|
// Return a debugging name for the task.
|
||||||
|
@ -846,47 +846,6 @@ Lex::next_token()
|
|||||||
return &this->token_;
|
return &this->token_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A trivial task which waits for THIS_BLOCKER to be clear and then
|
|
||||||
// clears NEXT_BLOCKER. THIS_BLOCKER may be NULL.
|
|
||||||
|
|
||||||
class Script_unblock : public Task
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Script_unblock(Task_token* this_blocker, Task_token* next_blocker)
|
|
||||||
: this_blocker_(this_blocker), next_blocker_(next_blocker)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
~Script_unblock()
|
|
||||||
{
|
|
||||||
if (this->this_blocker_ != NULL)
|
|
||||||
delete this->this_blocker_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Task_token*
|
|
||||||
is_runnable()
|
|
||||||
{
|
|
||||||
if (this->this_blocker_ != NULL && this->this_blocker_->is_blocked())
|
|
||||||
return this->this_blocker_;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
locks(Task_locker* tl)
|
|
||||||
{ tl->add(this, this->next_blocker_); }
|
|
||||||
|
|
||||||
void
|
|
||||||
run(Workqueue*)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
std::string
|
|
||||||
get_name() const
|
|
||||||
{ return "Script_unblock"; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
Task_token* this_blocker_;
|
|
||||||
Task_token* next_blocker_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// class Symbol_assignment.
|
// class Symbol_assignment.
|
||||||
|
|
||||||
// Add the symbol to the symbol table. This makes sure the symbol is
|
// Add the symbol to the symbol table. This makes sure the symbol is
|
||||||
@ -1347,8 +1306,7 @@ class Parser_closure
|
|||||||
};
|
};
|
||||||
|
|
||||||
// FILE was found as an argument on the command line. Try to read it
|
// FILE was found as an argument on the command line. Try to read it
|
||||||
// as a script. We've already read BYTES of data into P, but we
|
// as a script. Return true if the file was handled.
|
||||||
// ignore that. Return true if the file was handled.
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
read_input_script(Workqueue* workqueue, const General_options& options,
|
read_input_script(Workqueue* workqueue, const General_options& options,
|
||||||
@ -1356,9 +1314,11 @@ read_input_script(Workqueue* workqueue, const General_options& options,
|
|||||||
Dirsearch* dirsearch, Input_objects* input_objects,
|
Dirsearch* dirsearch, Input_objects* input_objects,
|
||||||
Input_group* input_group,
|
Input_group* input_group,
|
||||||
const Input_argument* input_argument,
|
const Input_argument* input_argument,
|
||||||
Input_file* input_file, const unsigned char*, off_t,
|
Input_file* input_file, Task_token* next_blocker,
|
||||||
Task_token* this_blocker, Task_token* next_blocker)
|
bool* used_next_blocker)
|
||||||
{
|
{
|
||||||
|
*used_next_blocker = false;
|
||||||
|
|
||||||
std::string input_string;
|
std::string input_string;
|
||||||
Lex::read_file(input_file, &input_string);
|
Lex::read_file(input_file, &input_string);
|
||||||
|
|
||||||
@ -1375,20 +1335,10 @@ read_input_script(Workqueue* workqueue, const General_options& options,
|
|||||||
if (yyparse(&closure) != 0)
|
if (yyparse(&closure) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// THIS_BLOCKER must be clear before we may add anything to the
|
|
||||||
// symbol table. We are responsible for unblocking NEXT_BLOCKER
|
|
||||||
// when we are done. We are responsible for deleting THIS_BLOCKER
|
|
||||||
// when it is unblocked.
|
|
||||||
|
|
||||||
if (!closure.saw_inputs())
|
if (!closure.saw_inputs())
|
||||||
{
|
return true;
|
||||||
// The script did not add any files to read. Note that we are
|
|
||||||
// not permitted to call NEXT_BLOCKER->unblock() here even if
|
|
||||||
// THIS_BLOCKER is NULL, as we do not hold the workqueue lock.
|
|
||||||
workqueue->queue(new Script_unblock(this_blocker, next_blocker));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
Task_token* this_blocker = NULL;
|
||||||
for (Input_arguments::const_iterator p = closure.inputs()->begin();
|
for (Input_arguments::const_iterator p = closure.inputs()->begin();
|
||||||
p != closure.inputs()->end();
|
p != closure.inputs()->end();
|
||||||
++p)
|
++p)
|
||||||
@ -1401,12 +1351,14 @@ read_input_script(Workqueue* workqueue, const General_options& options,
|
|||||||
nb = new Task_token(true);
|
nb = new Task_token(true);
|
||||||
nb->add_blocker();
|
nb->add_blocker();
|
||||||
}
|
}
|
||||||
workqueue->queue(new Read_symbols(options, input_objects, symtab,
|
workqueue->queue_soon(new Read_symbols(options, input_objects, symtab,
|
||||||
layout, dirsearch, &*p,
|
layout, dirsearch, &*p,
|
||||||
input_group, this_blocker, nb));
|
input_group, this_blocker, nb));
|
||||||
this_blocker = nb;
|
this_blocker = nb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*used_next_blocker = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -381,17 +381,16 @@ class Script_options
|
|||||||
};
|
};
|
||||||
|
|
||||||
// FILE was found as an argument on the command line, but was not
|
// FILE was found as an argument on the command line, but was not
|
||||||
// recognized as an ELF file. Try to read it as a script. We've
|
// recognized as an ELF file. Try to read it as a script. Return
|
||||||
// already read BYTES of data into P. Return true if the file was
|
// true if the file was handled. This has to handle /usr/lib/libc.so
|
||||||
// handled. This has to handle /usr/lib/libc.so on a GNU/Linux
|
// on a GNU/Linux system. *USED_NEXT_BLOCKER is set to indicate
|
||||||
// system.
|
// whether the function took over NEXT_BLOCKER.
|
||||||
|
|
||||||
bool
|
bool
|
||||||
read_input_script(Workqueue*, const General_options&, Symbol_table*, Layout*,
|
read_input_script(Workqueue*, const General_options&, Symbol_table*, Layout*,
|
||||||
Dirsearch*, Input_objects*, Input_group*,
|
Dirsearch*, Input_objects*, Input_group*,
|
||||||
const Input_argument*, Input_file*, const unsigned char* p,
|
const Input_argument*, Input_file*,
|
||||||
off_t bytes, Task_token* this_blocker,
|
Task_token* next_blocker, bool* used_next_blocker);
|
||||||
Task_token* next_blocker);
|
|
||||||
|
|
||||||
// FILE was found as an argument to --script (-T).
|
// FILE was found as an argument to --script (-T).
|
||||||
// Read it as a script, and execute its contents immediately.
|
// Read it as a script, and execute its contents immediately.
|
||||||
|
10
gold/token.h
10
gold/token.h
@ -48,6 +48,10 @@ class Task_list
|
|||||||
empty() const
|
empty() const
|
||||||
{ return this->head_ == NULL; }
|
{ return this->head_ == NULL; }
|
||||||
|
|
||||||
|
// Add T to the head of the list.
|
||||||
|
void
|
||||||
|
push_front(Task* t);
|
||||||
|
|
||||||
// Add T to the end of the list.
|
// Add T to the end of the list.
|
||||||
void
|
void
|
||||||
push_back(Task* t);
|
push_back(Task* t);
|
||||||
@ -166,6 +170,12 @@ class Task_token
|
|||||||
add_waiting(Task* t)
|
add_waiting(Task* t)
|
||||||
{ this->waiting_.push_back(t); }
|
{ this->waiting_.push_back(t); }
|
||||||
|
|
||||||
|
// Add T to the front of the list of tasks waiting for this token to
|
||||||
|
// be released.
|
||||||
|
void
|
||||||
|
add_waiting_front(Task* t)
|
||||||
|
{ this->waiting_.push_front(t); }
|
||||||
|
|
||||||
// Remove the first Task waiting for this token to be released, and
|
// Remove the first Task waiting for this token to be released, and
|
||||||
// return it. Return NULL if no Tasks are waiting.
|
// return it. Return NULL if no Tasks are waiting.
|
||||||
Task*
|
Task*
|
||||||
|
@ -50,6 +50,24 @@ Task_list::push_back(Task* t)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add T to the front of the list.
|
||||||
|
|
||||||
|
inline void
|
||||||
|
Task_list::push_front(Task* t)
|
||||||
|
{
|
||||||
|
gold_assert(t->list_next() == NULL);
|
||||||
|
if (this->head_ == NULL)
|
||||||
|
{
|
||||||
|
this->head_ = t;
|
||||||
|
this->tail_ = t;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
t->set_list_next(this->head_);
|
||||||
|
this->head_ = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Remove and return the first Task waiting for this lock to be
|
// Remove and return the first Task waiting for this lock to be
|
||||||
// released.
|
// released.
|
||||||
|
|
||||||
@ -130,19 +148,25 @@ Workqueue::~Workqueue()
|
|||||||
// waiting for a Token.
|
// waiting for a Token.
|
||||||
|
|
||||||
void
|
void
|
||||||
Workqueue::add_to_queue(Task_list* queue, Task* t)
|
Workqueue::add_to_queue(Task_list* queue, Task* t, bool front)
|
||||||
{
|
{
|
||||||
Hold_lock hl(this->lock_);
|
Hold_lock hl(this->lock_);
|
||||||
|
|
||||||
Task_token* token = t->is_runnable();
|
Task_token* token = t->is_runnable();
|
||||||
if (token != NULL)
|
if (token != NULL)
|
||||||
{
|
{
|
||||||
token->add_waiting(t);
|
if (front)
|
||||||
|
token->add_waiting_front(t);
|
||||||
|
else
|
||||||
|
token->add_waiting(t);
|
||||||
++this->waiting_;
|
++this->waiting_;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
queue->push_back(t);
|
if (front)
|
||||||
|
queue->push_front(t);
|
||||||
|
else
|
||||||
|
queue->push_back(t);
|
||||||
// Tell any waiting thread that there is work to do.
|
// Tell any waiting thread that there is work to do.
|
||||||
this->condvar_.signal();
|
this->condvar_.signal();
|
||||||
}
|
}
|
||||||
@ -153,16 +177,25 @@ Workqueue::add_to_queue(Task_list* queue, Task* t)
|
|||||||
void
|
void
|
||||||
Workqueue::queue(Task* t)
|
Workqueue::queue(Task* t)
|
||||||
{
|
{
|
||||||
this->add_to_queue(&this->tasks_, t);
|
this->add_to_queue(&this->tasks_, t, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a task to the front of the queue.
|
// Queue a task which should run soon.
|
||||||
|
|
||||||
void
|
void
|
||||||
Workqueue::queue_front(Task* t)
|
Workqueue::queue_soon(Task* t)
|
||||||
{
|
{
|
||||||
t->set_should_run_soon();
|
t->set_should_run_soon();
|
||||||
this->add_to_queue(&this->first_tasks_, t);
|
this->add_to_queue(&this->first_tasks_, t, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Queue a task which should run next.
|
||||||
|
|
||||||
|
void
|
||||||
|
Workqueue::queue_next(Task* t)
|
||||||
|
{
|
||||||
|
t->set_should_run_soon();
|
||||||
|
this->add_to_queue(&this->first_tasks_, t, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return whether to cancel the current thread.
|
// Return whether to cancel the current thread.
|
||||||
|
@ -205,10 +205,16 @@ class Workqueue
|
|||||||
void
|
void
|
||||||
queue(Task*);
|
queue(Task*);
|
||||||
|
|
||||||
// Add a new task to the front of the work queue. It will be the
|
// Add a new task to the work queue which should run soon. If the
|
||||||
// next task to run if it is ready.
|
// task is ready, it will be run before any tasks added using
|
||||||
|
// queue().
|
||||||
void
|
void
|
||||||
queue_front(Task*);
|
queue_soon(Task*);
|
||||||
|
|
||||||
|
// Add a new task to the work queue which should run next if it is
|
||||||
|
// ready.
|
||||||
|
void
|
||||||
|
queue_next(Task*);
|
||||||
|
|
||||||
// Process all the tasks on the work queue. This function runs
|
// Process all the tasks on the work queue. This function runs
|
||||||
// until all tasks have completed. The argument is the thread
|
// until all tasks have completed. The argument is the thread
|
||||||
@ -228,7 +234,7 @@ class Workqueue
|
|||||||
|
|
||||||
// Add a task to a queue.
|
// Add a task to a queue.
|
||||||
void
|
void
|
||||||
add_to_queue(Task_list* queue, Task* t);
|
add_to_queue(Task_list* queue, Task* t, bool front);
|
||||||
|
|
||||||
// Find a runnable task, or wait for one.
|
// Find a runnable task, or wait for one.
|
||||||
Task*
|
Task*
|
||||||
|
Loading…
Reference in New Issue
Block a user