You should never have the Main thread lock or wait for anything (if you are, then you're a naughty boy avarisc >:C ). What you should do is send the method that you want to be called into a pool that is consumed by the Main thread when it loops around, immediately after sending the method you need to wait for a semaphore (Win32 calls them Events or Signals) which will be fired at the end of the method.avarisc":1hit27xo said:OpenTK's Debug build actually provides nice error reporting. Unfortunately, for reasons unknown to me, it also prevents the application from starting. This program is incredibly version-sensitive when it comes to the libraries- far moreso than anything I've worked on before. It's quite frustrating at times. I can only imagine I'm doing something wrong, but I haven't the foggiest idea what.
Excellent info on the text! That had me running in circles for literally days before I decided to move on to more pressing tasks. Never considered threading to be the culprit. Resolving that may take some creativity- I'm not very experienced with threading, to be forthright. Let alone communicating with the program's main thread from its embedded interpreter's child thread :\ But at least it's a lead to follow.
Excuse the C++:
C++:
class WorkPool {
public:
typedef void ( * function_t )( void * const _data );
// Job structure
typedef struct job_s {
job_s( function_t _function, void * const _data ) {
function = _function;
data = _data;
}
function_t function;
void * data;
} job_t;
Array<job_t> jobs; // Job List
Mutex jobLock;
// Add job and its data to the queue
void AddJob( function_t _job, void * const _data ) {
jobLock.Lock(); // Prevents adding a job while the list is being consumed
jobs.Add( <span style="color: #0000dd;">new job_t( _job, _data ) );
jobLock.Unlock(); // Allows adding a job while the list is being consumed
}
void RunNextJob() {
job_t * const job = jobs.Next(); // Remove the first job from the list
job->function( job->data ); // Run the function with the data
<span style="color: #0000dd;">delete( job ); // Delete the job
}
};
class MainThread {
public:
WorkPool workPool;
void Loop() {
// If there's work to be done
if ( workPool.jobs.Count() > <span style="color: #0000dd;">0 ) {
jobLock.Lock(); // Prevents jobs from being added
while ( workPool.jobs.Count() ) {
workPool.RunNextJob(); // Run jobs until they are all consumed
}
jobLock.Unlock(); // Allows jobs to be added
}
ReadInputs();
UpdateState();
DrawState();
}
};
static MainThread mainThread;
class Thread {
public:
Signal signal;
void DoStuffThreaded() {
// Doing some threaded stuff
signal.Reset(); // Lower the signal so we can wait for it in a moment
mainThread.workPool.AddJob( ( WorkPool::function_t )DoStuffMainThread, <span style="color: #0000dd;">this );
signal.WaitFor(); // Wait for the signal to be raised
}
static void DoStuffMainThread( Thread * const _thread ) {
// Doing some main thread stuff
_thread->signal.Raise(); // Raise signal at the end of method
}
};
That is something like what I have for my work's codebase with a similar scenario. You want to push the function you want to do on the main thread into a list for the main thread to be consumed, then you want to wait for that specific function to be consumed.
EDIT: Also the only version of GL that mobile is compatible with is GL 4.3 which has full support of GLES 3.0.
GL2 and GLES2 are very different. If you have plans for mobile you'll be writing a new GL renderer.