Re: [AD] Exorcising END_OF_MAIN for Allegro 5 |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On 2008-07-14, Peter Hull <peterhull90@xxxxxxxxxx> wrote:
> On 7/14/08, Peter Wang <novalazy@xxxxxxxxxx> wrote:
> > The problem used to be that one of the Mac libraries needed to take over
> > the main thread, so we had to relegate the user's code to another
> > thread. I hope it has changed.
> Right, the OS will only deliver events to the main thread but in
> Allegro 4 there was nowhere in the user's code where we could reliably
> receive and dispatch the events. Magic main is used to run the user's
> main() in a second thread. A5 uses the same design at the moment. We
> could get around this if we require the user to call al_wait_for_event
> regularly (which I think is not the current case) or figure out some
> way to return from al_init but in a different thread (longjmp,
> ucontext or similar)
This is an interesting idea!
Can you do something with the attached code? This is the first time I've used
ucontext so it's probably not 100% correct. I get this output:
main entered in [b7e4e6c0]
thread_func in [b7e4db90]
main resumed in [b7e4db90]
hijacker in [b7e4e6c0]
Peter
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
#include <unistd.h>
ucontext_t uc1;
ucontext_t uc2;
char st2[8192];
pthread_t thread;
void *thread_func(void *arg)
{
printf("thread_func in [%lx]\n", pthread_self());
/* Resume into main. */
setcontext(&uc1);
/* Unreachable. */
abort();
(void) arg;
}
void hijacker(void)
{
/* Create a thread to resume main in. */
pthread_create(&thread, NULL, thread_func, NULL);
/* We should be in the primordial thread. */
printf("hijacker in [%lx]\n", pthread_self());
}
int main(void)
{
printf("main entered in [%lx]\n", pthread_self());
/* Run the hijacker on a different stack. */
getcontext(&uc2);
uc2.uc_link = NULL; /* no successor */
uc2.uc_stack.ss_sp = st2;
uc2.uc_stack.ss_size = sizeof st2;
makecontext(&uc2, hijacker, 0);
swapcontext(&uc1, &uc2);
/* uc1 resumes here. */
printf("main resumed in [%lx]\n", pthread_self());
sleep(2);
return 0;
}