Revert "Work in progress"

This reverts commit ef35aa7954
because it contained too much wrong things that I won't be
using. I'll re-commit stuff from it after that that I do
want to keep.
This commit is contained in:
Aleric Inglewood
2013-02-23 20:00:13 +01:00
parent ef35aa7954
commit 4851cc174e
14 changed files with 75 additions and 235 deletions

View File

@@ -82,8 +82,7 @@ void AIStateMachine::setMaxCount(F32 StateMachineMaxTime)
void AIStateMachine::run(AIStateMachine* parent, state_type new_parent_state, bool abort_parent, bool on_abort_signal_parent)
{
DoutEntering(dc::statemachine, "AIStateMachine::run(" << (void*)parent << ", " << (parent ? parent->state_str(new_parent_state) : "NA") <<
", " << abort_parent << ", " << on_abort_signal_parent << ") [" << (void*)this << "]");
DoutEntering(dc::statemachine, "AIStateMachine::run(" << (void*)parent << ", " << (parent ? parent->state_str(new_parent_state) : "NA") << ", " << abort_parent << ") [" << (void*)this << "]");
// Must be the first time we're being run, or we must be called from a callback function.
llassert(!mParent || mState == bs_callback);
llassert(!mCallback || mState == bs_callback);
@@ -114,7 +113,7 @@ void AIStateMachine::run(AIStateMachine* parent, state_type new_parent_state, bo
// Mark that run() has been called, in case we're being called from a callback function.
mState = bs_initialize;
// Set mIdle to false and add statemachine to continued_statemachines-- or, when boosted, run the statemachine till it finished or goes idle.
// Set mIdle to false and add statemachine to continued_statemachines.
mSetStateLock.lock();
locked_cont();
}
@@ -141,7 +140,7 @@ void AIStateMachine::run(callback_type::signal_type::slot_type const& slot)
// Mark that run() has been called, in case we're being called from a callback function.
mState = bs_initialize;
// Set mIdle to false and add statemachine to continued_statemachines-- or, when boosted, run the statemachine till it finished or goes idle.
// Set mIdle to false and add statemachine to continued_statemachines.
mSetStateLock.lock();
locked_cont();
}
@@ -149,11 +148,9 @@ void AIStateMachine::run(callback_type::signal_type::slot_type const& slot)
void AIStateMachine::idle(void)
{
DoutEntering(dc::statemachine, "AIStateMachine::idle() [" << (void*)this << "]");
llassert(mInsideMultiplexImpl);
mSetStateLock.lock();
llassert(is_main_thread());
llassert(!mIdle);
mIdle = true;
mSetStateLock.unlock();
mSleep = 0;
#ifdef SHOW_ASSERT
mCalledThreadUnsafeIdle = true;
@@ -163,12 +160,9 @@ void AIStateMachine::idle(void)
void AIStateMachine::idle(state_type current_run_state)
{
DoutEntering(dc::statemachine, "AIStateMachine::idle(" << state_str(current_run_state) << ") [" << (void*)this << "]");
llassert(mInsideMultiplexImpl); // Only boosted state machines can come here as non-main thread because you may only get here from multiplex_impl().
mSetStateLock.lock();
// If two different threads call multiplex_impl() (boosted state machines) then that should happen serialized:
// only one thread may call multiplex() at any given time. Hence, it is impossible that idle() is called while
// we are already idle.
llassert(is_main_thread());
llassert(!mIdle);
mSetStateLock.lock();
// Only go idle if the run state is (still) what we expect it to be.
// Otherwise assume that another thread called set_state() and continue running.
if (current_run_state == mRunState)
@@ -202,7 +196,6 @@ void AIStateMachine::locked_cont(void)
mIdle = false;
bool not_active = mActive == as_idle;
mIdleActive.unlock();
mBoost = thread_safe_impl();
// mActive is only changed in AIStateMachine::mainloop, by the main-thread, and
// here, possibly by any thread. However, after setting mIdle to false above, it
// is impossible for any thread to come here, until after the main-thread called
@@ -217,15 +210,8 @@ void AIStateMachine::locked_cont(void)
// to release mSetStateLock here, with as advantage that if we're not the main-
// thread and not_active is true, then the main-thread won't block when it has
// a timer running that times out and calls set_state().
// Finally, if mBoost is true then not_active is not going to be tested and
// mActive is not going to be changed, so then we're done with this lock too.
mSetStateLock.unlock();
if (mBoost)
{
// Run statemachine until it is finished or idle again.
multiplex(0);
}
else if (not_active)
if (not_active)
{
AIWriteAccess<csme_type> csme_w(sContinuedStateMachinesAndMainloopEnabled);
// See above: it is not possible that mActive was changed since not_active
@@ -250,6 +236,9 @@ void AIStateMachine::set_state(state_type state)
// Stop race condition of multiple threads calling cont() or set_state() here.
mSetStateLock.lock();
// Do not call set_state() unless running.
llassert(mState == bs_run || !is_main_thread());
// If this function is called from another thread than the main thread, then we have to ignore
// it if we're not idle and the state is less than the current state. The main thread must
// be able to change the state to anything (also smaller values). Note that that only can work
@@ -290,11 +279,8 @@ void AIStateMachine::set_state(state_type state)
return; // Ignore.
}
// Do not call set_state() from multiplex_impl unless running.
llassert(mState == bs_run || !mInsideMultiplexImpl);
// Do not call idle() when set_state is called from another thread; use idle(state_type) instead.
llassert(!mCalledThreadUnsafeIdle || AIThreadID::in_main_thread());
llassert(!mCalledThreadUnsafeIdle || is_main_thread());
// Change mRunState to the requested value.
if (mRunState != state)
@@ -307,15 +293,7 @@ void AIStateMachine::set_state(state_type state)
if (mIdle)
locked_cont(); // This unlocks mSetStateLock.
else
{
// The state was changed while not being idle.
// Note that if thread_safe_impl() returns true now then we don't need to call multiplex() here
// when we ended up here from multiplex(). However, if we end up here as the result of an
// external state change while the state machine is running in the main thread, then we can't
// call multiplex here; it would be too dangerous. In that case we let the main thread pick
// up this state.
mSetStateLock.unlock();
}
// If we get here then mIdle is false, so only mRunState can still be changed but we won't
// call locked_cont() anymore. When the main thread finally picks up on the state change,
@@ -476,7 +454,6 @@ void AIStateMachine::multiplex(U64 current_time)
// amount of time has passed.
if (mSleep != 0)
{
llassert(!mBoost); // Sleeping MUST be done in the main thread: thread_safe_impl() should have returned false.
if (mSleep < 0)
{
if (++mSleep)
@@ -498,90 +475,11 @@ void AIStateMachine::multiplex(U64 current_time)
{
mAborted = false;
mState = bs_run;
#ifdef SHOW_ASSERT
mInsideMultiplexImpl = true;
#endif
initialize_impl();
#ifdef SHOW_ASSERT
mInsideMultiplexImpl = false;
#endif
if (mAborted || mState != bs_run)
{
mBoost = false;
return;
}
mSetStateLock.lock();
mBoost = thread_safe_impl();
if (!mBoost && !AIThreadID::in_main_thread())
{
// Pass running on the main thread.
mIdle = true;
locked_cont();
return;
}
mSetStateLock.unlock();
}
if (!mBoost)
{
llassert(AIThreadID::in_main_thread());
#ifdef SHOW_ASSERT
mInsideMultiplexImpl = true;
#endif
multiplex_impl();
#ifdef SHOW_ASSERT
mInsideMultiplexImpl = false;
#endif
}
else
{
if (mState != bs_run)
return;
mSetStateLock.lock();
llassert(!mIdle); // We should never get here when idle.
if (!mMultiplexMutex.tryLock()) // Point A
{
// If another thread is already already calling multiplex_impl() then we can't do that too.
// However, instead of blocking we simply return: by getting here it is guaranteed that
// the other thread will do at least one more test of 'mState == bs_run && !mIdle' before
// stopping to run the statemachine.
// The reason for that is that if another thread had mMultiplexMutex at point A, while
// we had mSetStateLock, then the other thread has to be between point B and point C
// because that is the only area where mSetStateLock is unlocked while mMultiplexMutex
// is locked, and the test follows this area.
mSetStateLock.unlock();
return;
}
do
{
mSetStateLock.unlock(); // Point B
#ifdef SHOW_ASSERT
mInsideMultiplexImpl = true;
#endif
multiplex_impl();
#ifdef SHOW_ASSERT
mInsideMultiplexImpl = false;
#endif
mSetStateLock.lock(); // Point C
// The state might have changed, check if we may still run outside the main thread.
mBoost = thread_safe_impl();
if (!mBoost && !AIThreadID::in_main_thread())
{
mMultiplexMutex.unlock();
// Pass running on the main thread.
mIdle = true;
locked_cont();
return;
}
}
while (mState == bs_run && !mIdle);
mMultiplexMutex.unlock();
mSetStateLock.unlock();
}
multiplex_impl();
}
//static
@@ -692,10 +590,6 @@ void AIStateMachine::flush(void)
for (active_statemachines_type::iterator iter = active_statemachines.begin(); iter != active_statemachines.end(); ++iter)
{
AIStateMachine& statemachine(iter->statemachine());
#ifdef SHOW_ASSERT
// Make assertions happy.
statemachine.mInsideMultiplexImpl = true;
#endif
if (statemachine.abortable())
{
// We can't safely call abort() here for non-running (run() was called, but they weren't initialized yet) statemachines,

View File

@@ -176,7 +176,6 @@
// Should return a stringified value of run_state.
//
class AIStateMachine {
protected:
//! The type of mState
enum base_state_type {
bs_initialize,
@@ -214,15 +213,12 @@ class AIStateMachine {
base_state_type mState; //!< State of the base class.
bool mIdle; //!< True if this state machine is not running.
bool mAborted; //!< True after calling abort() and before calling run().
bool mBoost; //!< True when not being run by the main thread, but by which ever thread is changing the state.
active_type mActive; //!< Whether statemachine is idle, queued to be added to the active list, or already on the active list (not used for boosted SM).
S64 mSleep; //!< Non-zero while the state machine is sleeping (not used for boosted SM).
LLMutex mIdleActive; //!< Used for atomic operations on the pair mIdle / mActive (not used for boosted SM).
LLMutex mMultiplexMutex; //!< Used for boosted state machines, locked during multiplexing.
active_type mActive; //!< Whether statemachine is idle, queued to be added to the active list, or already on the active list.
S64 mSleep; //!< Non-zero while the state machine is sleeping.
LLMutex mIdleActive; //!< Used for atomic operations on the pair mIdle / mActive.
#ifdef SHOW_ASSERT
AIThreadID mContThread; //!< Thread that last called locked_cont().
bool mCalledThreadUnsafeIdle; //!< Set to true when idle() is called.
bool mInsideMultiplexImpl; //!< Set to true while running a boosted state machine (also set while inside initialize_impl).
#endif
// Callback facilities.
@@ -254,11 +250,10 @@ class AIStateMachine {
public:
//! Create a non-running state machine.
AIStateMachine(void) : mState(bs_initialize), mIdle(true), mAborted(true), mActive(as_idle), mSleep(0),
AIStateMachine(void) : mState(bs_initialize), mIdle(true), mAborted(true), mActive(as_idle), mSleep(0), mParent(NULL), mCallback(NULL)
#ifdef SHOW_ASSERT
mContThread(AIThreadID::none), mCalledThreadUnsafeIdle(false),
, mContThread(AIThreadID::none), mCalledThreadUnsafeIdle(false)
#endif
mParent(NULL), mCallback(NULL), mRunState(0)
{ }
protected:
@@ -379,10 +374,6 @@ class AIStateMachine {
//! Return a stringified state, for debugging purposes.
char const* state_str(state_type state);
protected:
//! Return mState.
base_state_type base_state(void) const { return mState; }
private:
static void add_continued_statemachines(AIReadAccess<csme_type>& csme_r);
static void dowork(void);
@@ -421,10 +412,6 @@ class AIStateMachine {
// Handle cleaning up from initialization (or post abort) state.
virtual void finish_impl(void) = 0;
// Determine if it is thread-safe to run the current state in another thread than the main-thread.
// Only called while mSetStateLock is locked, may ONLY access mState and mRunState.
virtual bool thread_safe_impl(void) const { return false; }
// Implemenation of state_str for run states.
virtual char const* state_str_impl(state_type run_state) const = 0;
};

View File

@@ -33,8 +33,7 @@
enum timer_state_type {
AITimer_start = AIStateMachine::max_state,
AITimer_expired,
AITimer_abort
AITimer_expired
};
char const* AITimer::state_str_impl(state_type run_state) const
@@ -43,7 +42,6 @@ char const* AITimer::state_str_impl(state_type run_state) const
{
AI_CASE_RETURN(AITimer_start);
AI_CASE_RETURN(AITimer_expired);
AI_CASE_RETURN(AITimer_abort);
}
return "UNKNOWN STATE";
}
@@ -54,12 +52,6 @@ void AITimer::initialize_impl(void)
set_state(AITimer_start);
}
void AITimer::request_abort(void)
{
mFrameTimer.cancel();
set_state(AITimer_abort);
}
void AITimer::expired(void)
{
set_state(AITimer_expired);
@@ -72,7 +64,7 @@ void AITimer::multiplex_impl(void)
case AITimer_start:
{
mFrameTimer.create(mInterval, boost::bind(&AITimer::expired, this));
idle(AITimer_start);
idle();
break;
}
case AITimer_expired:
@@ -80,11 +72,6 @@ void AITimer::multiplex_impl(void)
finish();
break;
}
case AITimer_abort:
{
abort();
break;
}
}
}

View File

@@ -82,11 +82,6 @@ class AITimer : public AIStateMachine {
*/
F64 getInterval(void) const { return mInterval; }
/**
* @brief Abort the timer from another thread.
*/
void request_abort(void);
protected:
// Call finish() (or abort()), not delete.
/*virtual*/ ~AITimer() { DoutEntering(dc::statemachine, "~AITimer() [" << (void*)this << "]"); mFrameTimer.cancel(); }

View File

@@ -33,13 +33,26 @@
#include "aihttptimeoutpolicy.h"
#include "llcontrol.h"
enum curleasyrequeststatemachine_state_type {
AICurlEasyRequestStateMachine_addRequest = AIStateMachine::max_state,
AICurlEasyRequestStateMachine_waitAdded,
AICurlEasyRequestStateMachine_added,
AICurlEasyRequestStateMachine_timedOut, // This must be smaller than the rest, so they always overrule.
AICurlEasyRequestStateMachine_finished,
AICurlEasyRequestStateMachine_removed, // The removed states must be largest two, so they are never ignored.
AICurlEasyRequestStateMachine_removed_after_finished,
AICurlEasyRequestStateMachine_bad_file_descriptor
};
char const* AICurlEasyRequestStateMachine::state_str_impl(state_type run_state) const
{
switch(run_state)
{
AI_CASE_RETURN(AICurlEasyRequestStateMachine_addRequest);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_waitAdded);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_added);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_timedOut);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_finished);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_removed);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_removed_after_finished);
AI_CASE_RETURN(AICurlEasyRequestStateMachine_bad_file_descriptor);
@@ -64,12 +77,14 @@ void AICurlEasyRequestStateMachine::initialize_impl(void)
// CURL-THREAD
void AICurlEasyRequestStateMachine::added_to_multi_handle(AICurlEasyRequest_wat&)
{
set_state(AICurlEasyRequestStateMachine_added);
}
// CURL-THREAD
void AICurlEasyRequestStateMachine::finished(AICurlEasyRequest_wat&)
{
mFinished = true;
set_state(AICurlEasyRequestStateMachine_finished);
}
// CURL-THREAD
@@ -115,11 +130,15 @@ void AICurlEasyRequestStateMachine::multiplex_impl(void)
// immediately after this call.
mAdded = true;
mCurlEasyRequest.addRequest(); // This causes the state to be changed, now or later, to
// AICurlEasyRequestStateMachine_added, then
// AICurlEasyRequestStateMachine_finished and then
// AICurlEasyRequestStateMachine_removed_after_finished.
// The first two states might be skipped thus, and the state at this point is one of
// 1) AICurlEasyRequestStateMachine_waitAdded (idle)
// 2) AICurlEasyRequestStateMachine_removed_after_finished (running)
// 2) AICurlEasyRequestStateMachine_added (running)
// 3) AICurlEasyRequestStateMachine_finished (running)
// 4) AICurlEasyRequestStateMachine_removed_after_finished (running)
if (mTotalDelayTimeout > 0.f)
{
@@ -132,16 +151,22 @@ void AICurlEasyRequestStateMachine::multiplex_impl(void)
}
break;
}
case AICurlEasyRequestStateMachine_waitAdded:
case AICurlEasyRequestStateMachine_added:
{
// Nothing to do.
idle(AICurlEasyRequestStateMachine_waitAdded);
// The request was added to the multi handle. This is a no-op, which is good cause
// this state might be skipped anyway ;).
idle(current_state); // Wait for the next event.
// The state at this point is one of
// 1) AICurlEasyRequestStateMachine_added (idle)
// 2) AICurlEasyRequestStateMachine_finished (running)
// 3) AICurlEasyRequestStateMachine_removed_after_finished (running)
break;
}
case AICurlEasyRequestStateMachine_timedOut:
{
// It is possible that exactly at this point the state changes into
// AICurlEasyRequestStateMachine_removed_after_finished, with as result that mTimedOut
// AICurlEasyRequestStateMachine_finished, with as result that mTimedOut
// is set while we will continue with that state. Hence that mTimedOut
// is explicitly reset in that state.
@@ -154,6 +179,7 @@ void AICurlEasyRequestStateMachine::multiplex_impl(void)
idle(current_state); // Wait till AICurlEasyRequestStateMachine::removed_from_multi_handle() is called.
break;
}
case AICurlEasyRequestStateMachine_finished:
case AICurlEasyRequestStateMachine_removed_after_finished:
{
if (!mHandled)
@@ -165,8 +191,7 @@ void AICurlEasyRequestStateMachine::multiplex_impl(void)
{
// Stop the timer. Note that it's the main thread that generates timer events,
// so we're certain that there will be no time out anymore if we reach this point.
// Note that we can't call abort() directly here, as we're a boosted statemachine.
mTimer->request_abort();
mTimer->abort();
}
// The request finished and either data or an error code is available.
@@ -174,6 +199,12 @@ void AICurlEasyRequestStateMachine::multiplex_impl(void)
easy_request_w->processOutput();
}
if (current_state == AICurlEasyRequestStateMachine_finished)
{
idle(current_state); // Wait till AICurlEasyRequestStateMachine::removed_from_multi_handle() is called.
break;
}
// See above.
mTimedOut = false;
/* Fall-Through */
@@ -233,9 +264,7 @@ void AICurlEasyRequestStateMachine::finish_impl(void)
// Note that even if the timer expired, it wasn't deleted because we used AIPersistentTimer; so mTimer is still valid.
// Stop the timer, if it's still running.
if (!mHandled)
{
mTimer->request_abort();
}
mTimer->abort();
}
// Auto clean up ourselves.
kill();

View File

@@ -35,15 +35,6 @@
#include "aitimer.h"
#include "aicurl.h"
enum curleasyrequeststatemachine_state_type {
AICurlEasyRequestStateMachine_addRequest = AIStateMachine::max_state,
AICurlEasyRequestStateMachine_waitAdded,
AICurlEasyRequestStateMachine_timedOut, // This must be smaller than the rest, so they always overrule.
AICurlEasyRequestStateMachine_removed, // The removed states must be largest two, so they are never ignored.
AICurlEasyRequestStateMachine_removed_after_finished,
AICurlEasyRequestStateMachine_bad_file_descriptor
};
// A curl easy request state machine.
//
// Before calling cersm.run() initialize the object (cersm) as follows:

View File

@@ -832,9 +832,8 @@ class AICurlThread : public LLThread
{
public:
static AICurlThread* sInstance;
LLMutex mWakeUpMutex; // Set while a thread is waking up the curl thread.
LLMutex mWakeUpFlagMutex; // Set when the curl thread is sleeping (in or about to enter select()).
bool mWakeUpFlag; // Protected by mWakeUpFlagMutex.
LLMutex mWakeUpMutex;
bool mWakeUpFlag; // Protected by mWakeUpMutex.
public:
// MAIN-THREAD
@@ -1068,10 +1067,11 @@ void AICurlThread::cleanup_wakeup_fds(void)
#endif
}
// OTHER THREADS
// MAIN-THREAD
void AICurlThread::wakeup_thread(bool stop_thread)
{
DoutEntering(dc::curl, "AICurlThread::wakeup_thread");
llassert(is_main_thread());
// If we are already exiting the viewer then return immediately.
if (!mRunning)
@@ -1079,20 +1079,12 @@ void AICurlThread::wakeup_thread(bool stop_thread)
// Last time we are run?
if (stop_thread)
mRunning = false; // Thread-safe because all other threads were already stopped.
// Stop two threads running the following code at the same time.
if (!mWakeUpMutex.tryLock())
{
// If another thread is already busy waking up the curl thread, then we don't have to.
return;
}
mRunning = false;
// Try if curl thread is still awake and if so, pass the new commands directly.
if (mWakeUpFlagMutex.tryLock())
if (mWakeUpMutex.tryLock())
{
mWakeUpFlag = true;
mWakeUpFlagMutex.unlock();
mWakeUpMutex.unlock();
return;
}
@@ -1119,10 +1111,7 @@ void AICurlThread::wakeup_thread(bool stop_thread)
{
len = write(mWakeUpFd_in, "!", 1);
if (len == -1 && errno == EAGAIN)
{
mWakeUpMutex.unlock();
return; // Unread characters are still in the pipe, so no need to add more.
}
}
while(len == -1 && errno == EINTR);
if (len == -1)
@@ -1131,7 +1120,6 @@ void AICurlThread::wakeup_thread(bool stop_thread)
}
llassert_always(len == 1);
#endif
mWakeUpMutex.unlock();
}
apr_status_t AICurlThread::join_thread(void)
@@ -1259,9 +1247,9 @@ void AICurlThread::process_commands(AICurlMultiHandle_wat const& multi_handle_w)
command_queue_wat command_queue_w(command_queue);
if (command_queue_w->empty())
{
mWakeUpFlagMutex.lock();
mWakeUpMutex.lock();
mWakeUpFlag = false;
mWakeUpFlagMutex.unlock();
mWakeUpMutex.unlock();
break;
}
// Move the next command from the queue into command_being_processed.
@@ -1324,10 +1312,10 @@ void AICurlThread::run(void)
// Process every command in command_queue before filling the fd_set passed to select().
for(;;)
{
mWakeUpFlagMutex.lock();
mWakeUpMutex.lock();
if (mWakeUpFlag)
{
mWakeUpFlagMutex.unlock();
mWakeUpMutex.unlock();
process_commands(multi_handle_w);
continue;
}
@@ -1336,7 +1324,7 @@ void AICurlThread::run(void)
// wakeup_thread() is also called after setting mRunning to false.
if (!mRunning)
{
mWakeUpFlagMutex.unlock();
mWakeUpMutex.unlock();
break;
}
@@ -1412,7 +1400,7 @@ void AICurlThread::run(void)
#endif
#endif
ready = select(nfds, read_fd_set, write_fd_set, NULL, &timeout);
mWakeUpFlagMutex.unlock();
mWakeUpMutex.unlock();
#ifdef CWDEBUG
#ifdef DEBUG_CURLIO
Dout(dc::finish|cond_error_cf(ready == -1), ready);

View File

@@ -84,11 +84,6 @@ public:
#include "aihttptimeout.h"
// If this is set, treat dc::curlio as off in the assertion below.
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
bool gCurlIo;
#endif
namespace AICurlPrivate {
namespace curlthread {
@@ -174,7 +169,7 @@ bool HTTPTimeout::data_received(size_t n/*,*/
// using CURLOPT_DEBUGFUNCTION. Note that mDebugIsHeadOrGetMethod is only valid when the debug channel 'curlio' is on,
// because it is set in the debug callback function.
// This is also normal if we received a HTTP header with an error status, since that can interrupt our upload.
Debug(llassert(upload_error_status || AICurlEasyRequest_wat(*mLockObj)->mDebugIsHeadOrGetMethod || !dc::curlio.is_on() || gCurlIo));
Debug(llassert(upload_error_status || AICurlEasyRequest_wat(*mLockObj)->mDebugIsHeadOrGetMethod || !dc::curlio.is_on()));
// 'Upload finished' detection failed, generate it now.
upload_finished();
}

View File

@@ -133,9 +133,5 @@ class HTTPTimeout : public LLRefCount {
} // namespace curlthread
} // namespace AICurlPrivate
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
extern bool gCurlIo;
#endif
#endif

View File

@@ -202,9 +202,6 @@ public:
// The name of the derived responder object. For debugging purposes.
virtual char const* getName(void) const = 0;
// Returning true causes AICurlEasyRequestStateMachine::multiplex_impl to be called from non-main threads.
virtual bool thread_safe_complete(void) const { return false; }
protected:
// Derived classes can override this to get the HTML headers that were received, when the message is completed.
// Only actually called for classes that implement a needsHeaders() that returns true.

View File

@@ -83,24 +83,6 @@ LLURLRequest::LLURLRequest(LLURLRequest::ERequestAction action, std::string cons
{
}
bool LLURLRequest::thread_safe_impl(void) const
{
if (base_state() == bs_run &&
(mRunState == AICurlEasyRequestStateMachine_removed_after_finished ||
mRunState == AICurlEasyRequestStateMachine_addRequest) &&
mResponder->thread_safe_complete())
{
return true;
}
// AICurlEasyRequestStateMachine::initialize_impl is thread safe because the statemachine
// will only just have been created and no other thread can know of this instance.
if (base_state() == bs_initialize)
return true;
return false;
}
void LLURLRequest::initialize_impl(void)
{
// If the header is "Pragma" with no value, the caller intends to

View File

@@ -122,9 +122,6 @@ class LLURLRequest : public AICurlEasyRequestStateMachine {
protected:
// Handle initializing the object.
/*virtual*/ void initialize_impl(void);
// Return true if current state is thread safe.
/*virtual*/ bool thread_safe_impl(void) const;
};
#endif // LL_LLURLREQUEST_H

View File

@@ -260,6 +260,10 @@ extern S32 gStartImageHeight;
// local globals
//
#if defined(CWDEBUG) || defined(DEBUG_CURLIO)
static bool gCurlIo;
#endif
static LLHost gAgentSimHost;
static BOOL gSkipOptionalUpdate = FALSE;

View File

@@ -338,8 +338,6 @@ public:
}
#endif
/*virtual*/ bool thread_safe_complete(void) const { return true; }
/*virtual*/ void completedRaw(U32 status, const std::string& reason,
const LLChannelDescriptors& channels,
const buffer_ptr_t& buffer)