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;
}


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/