Initial checkin of the Expander replacement app.
Redone from scratch because we don't have Dan Lee's code. Beta version. Testing is welcome. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7001 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,386 @@
|
||||
// license: public domain
|
||||
// authors: [email protected]
|
||||
|
||||
#include <GenericThread.h>
|
||||
|
||||
GenericThread::GenericThread(const char * a_thread_name, int32 a_priority, BMessage * a_message)
|
||||
:
|
||||
m_thread_data_store (a_message),
|
||||
m_thread_id (spawn_thread (private_thread_function, a_thread_name, a_priority, this)),
|
||||
m_execute_unit (create_sem(1, "m_execute_unit")),
|
||||
m_quit_requested (false),
|
||||
m_thread_is_paused (false)
|
||||
{
|
||||
if (m_thread_data_store == NULL)
|
||||
m_thread_data_store = new BMessage();
|
||||
}
|
||||
|
||||
GenericThread::~GenericThread()
|
||||
{
|
||||
kill_thread(m_thread_id);
|
||||
|
||||
delete_sem(m_execute_unit);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::ThreadFunction (void)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = ThreadStartup(); // Subclass and override this function
|
||||
if (status != B_OK)
|
||||
{
|
||||
ThreadStartupFailed (status);
|
||||
return (status);
|
||||
// is this the right thing to do?
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
if (HasQuitBeenRequested())
|
||||
{
|
||||
status = ThreadShutdown(); // Subclass and override this function
|
||||
if (status != B_OK)
|
||||
{
|
||||
ThreadShutdownFailed (status);
|
||||
return (status);
|
||||
// what do we do?
|
||||
}
|
||||
|
||||
delete this; // destructor
|
||||
}
|
||||
|
||||
BeginUnit();
|
||||
|
||||
status = ExecuteUnit(); // Subclass and override
|
||||
|
||||
if (status != B_OK)
|
||||
ExecuteUnitFailed (status); // Subclass and override
|
||||
|
||||
EndUnit();
|
||||
}
|
||||
|
||||
return (B_OK);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::ThreadStartup (void)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GenericThread::ExecuteUnit (void)
|
||||
{
|
||||
// This function is virtual.
|
||||
|
||||
// You would normally subclass and override this function
|
||||
// as it will provide you with Pause and Quit functionality
|
||||
// thanks to the unit management done by GenericThread::ThreadFunction()
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::ThreadShutdown (void)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ThreadStartupFailed (status_t a_status)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
Quit();
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ExecuteUnitFailed (status_t a_status)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
Quit();
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ThreadShutdownFailed (status_t a_status)
|
||||
{
|
||||
// This function is virtual.
|
||||
// Subclass and override this function.
|
||||
|
||||
// (is this good default behaviour?)
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Start (void)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
if (IsPaused())
|
||||
{
|
||||
status = release_sem (m_execute_unit);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
m_thread_is_paused = false;
|
||||
}
|
||||
|
||||
status = resume_thread (m_thread_id);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int32
|
||||
GenericThread::private_thread_function (void * a_simple_thread_ptr)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
status = ((GenericThread *) a_simple_thread_ptr)-> ThreadFunction();
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
BMessage *
|
||||
GenericThread::GetDataStore (void)
|
||||
{
|
||||
return (m_thread_data_store);
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::SetDataStore (BMessage * a_message)
|
||||
{
|
||||
m_thread_data_store = a_message;
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Pause (bool a_do_block, bigtime_t a_timeout)
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
if (a_do_block)
|
||||
status = acquire_sem(m_execute_unit);
|
||||
// thread will wait on semaphore
|
||||
else
|
||||
status = acquire_sem_etc(m_execute_unit, 1, B_RELATIVE_TIMEOUT, a_timeout);
|
||||
// thread will timeout
|
||||
|
||||
if (status == B_OK)
|
||||
{
|
||||
m_thread_is_paused = true;
|
||||
return (B_OK);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::Quit (void)
|
||||
{
|
||||
m_quit_requested = true;
|
||||
}
|
||||
|
||||
bool
|
||||
GenericThread::HasQuitBeenRequested (void)
|
||||
{
|
||||
return (m_quit_requested);
|
||||
}
|
||||
|
||||
bool
|
||||
GenericThread::IsPaused (void)
|
||||
{
|
||||
return (m_thread_is_paused);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Suspend (void)
|
||||
{
|
||||
return (suspend_thread(m_thread_id));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Resume (void)
|
||||
{
|
||||
release_sem(m_execute_unit); // to counteract Pause()
|
||||
m_thread_is_paused = false;
|
||||
|
||||
return (resume_thread(m_thread_id)); // to counteract Suspend()
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Kill (void)
|
||||
{
|
||||
return (kill_thread(m_thread_id));
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::ExitWithReturnValue (status_t a_return_value)
|
||||
{
|
||||
exit_thread(a_return_value);
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::SetExitCallback (void (*a_callback)(void*), void * a_data)
|
||||
{
|
||||
return (on_exit_thread(a_callback, a_data));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::WaitForThread (status_t * a_exit_value)
|
||||
{
|
||||
return (wait_for_thread(m_thread_id, a_exit_value));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::Rename (char * a_name)
|
||||
{
|
||||
return (rename_thread(m_thread_id, a_name));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::SendData (int32 a_code, void * a_buffer, size_t a_buffer_size)
|
||||
{
|
||||
return (send_data(m_thread_id, a_code, a_buffer, a_buffer_size));
|
||||
}
|
||||
|
||||
int32
|
||||
GenericThread::ReceiveData (thread_id * a_sender, void * a_buffer, size_t a_buffer_size)
|
||||
{
|
||||
return (receive_data(a_sender, a_buffer, a_buffer_size));
|
||||
}
|
||||
|
||||
bool
|
||||
GenericThread::HasData (void)
|
||||
{
|
||||
return (has_data(m_thread_id));
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::SetPriority (int32 a_new_priority)
|
||||
{
|
||||
return (set_thread_priority(m_thread_id, a_new_priority));
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::Snooze (bigtime_t a_microseconds)
|
||||
{
|
||||
Suspend();
|
||||
snooze(a_microseconds);
|
||||
Resume();
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::SnoozeUntil (bigtime_t a_microseconds, int a_timebase)
|
||||
{
|
||||
Suspend();
|
||||
snooze_until(a_microseconds, a_timebase);
|
||||
Resume();
|
||||
}
|
||||
|
||||
status_t
|
||||
GenericThread::GetInfo (thread_info * a_thread_info)
|
||||
{
|
||||
return (get_thread_info(m_thread_id, a_thread_info));
|
||||
}
|
||||
|
||||
thread_id
|
||||
GenericThread::GetThread (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.thread);
|
||||
}
|
||||
|
||||
team_id
|
||||
GenericThread::GetTeam (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.team);
|
||||
}
|
||||
|
||||
char *
|
||||
GenericThread::GetName (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.name);
|
||||
}
|
||||
|
||||
thread_state
|
||||
GenericThread::GetState (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.state);
|
||||
}
|
||||
|
||||
sem_id
|
||||
GenericThread::GetSemaphore (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.sem);
|
||||
}
|
||||
|
||||
int32
|
||||
GenericThread::GetPriority (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.priority);
|
||||
}
|
||||
|
||||
bigtime_t
|
||||
GenericThread::GetUserTime (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.user_time);
|
||||
}
|
||||
|
||||
bigtime_t
|
||||
GenericThread::GetKernelTime (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.kernel_time);
|
||||
}
|
||||
|
||||
void *
|
||||
GenericThread::GetStackBase (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.stack_base);
|
||||
}
|
||||
|
||||
void *
|
||||
GenericThread::GetStackEnd (void)
|
||||
{
|
||||
thread_info t_thread_info;
|
||||
GetInfo (& t_thread_info);
|
||||
return (t_thread_info.stack_end);
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::BeginUnit (void)
|
||||
{
|
||||
acquire_sem(m_execute_unit); // thread can not be paused until it releases semaphore
|
||||
}
|
||||
|
||||
void
|
||||
GenericThread::EndUnit (void)
|
||||
{
|
||||
release_sem(m_execute_unit); // thread can now be paused
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user