The Thread class is used to create processes that run independently from the main appication process.
If you create a thread from a task, any action that requires doing DOS I/O (e.g. DupLock() of currentdir, for example) will not occur.
Defines the hook to call when the low-level of the thread is ready.
Don't forget that you can use the h_Data field of the struct Hook to pass custom data.
#include <dos/dostags.h> #include <dos/dosextens.h> #include <dos/notify.h> #include <libraries/feelin.h>
#include <proto/feelin.h> #include <proto/exec.h> #include <proto/dos.h>
F_DECLARE_FEELIN;
Our thread code. Note well that we must return TRUE to FV_Thread_Hello and FV_Thread_Bye. Return FALSE to FV_Thread_Hello to indicate an initialization failure. If you don't return TRUE to FV_Thread_Bye, the process is removed by hand !!
struct FS_THREAD_DATA
{
    struct Task *Owner;
};
F_HOOKM(FThreadMsg *, Thread_Main, FS_Thread_Run)
{
    uint32 id_Pop = Msg->Public->id_Pop;
    uint32 id_Wait = Msg->Public->id_Wait;
    IFEELIN F_Log
    (
        0,
        "Thread_Main() Thread (0x%08lx) Public (0x%08lx) - Owner (0x%08lx)",
        Obj, Msg->Public, ((struct FS_THREAD_DATA *) Hook->h_Data)->Owner
    );
    for (;;)
    {
        FThreadMsg *msg = (FThreadMsg *) IFEELIN F_Do(Obj, id_Pop);
        if (msg)
        {
            IFEELIN F_Log(0,"Msg 0x%08lx - Action 0x%08lx", msg, msg->Action);
            switch (msg->Action)
            {
                case FV_Thread_Hello:
                {
                    msg->Return = TRUE;
                }
                break;
                case FV_Thread_Bye:
                {
                    IFEELIN F_Log(FV_LOG_USER, "bye");
                    msg->Return = TRUE;
                    return msg;
                }
                break;
            }
            IEXEC ReplyMsg((struct Message *) msg);
        }
        else
        {
            IFEELIN F_Log(FV_LOG_USER, "waiting...");
            IFEELIN F_Do(Obj, id_Wait, 0);
        }
    }
}
Main code of our demo
int main(void)
{
    struct Hook thread_hook;
    struct FS_THREAD_DATA thread_data;
    thread_data.Owner = IEXEC FindTask(NULL);
    thread_hook.h_Entry = (HOOKFUNC) Thread_Main;
    thread_hook.h_Data = &thread_data;
    if (F_FEELIN_OPEN)
    {
        FObject thread = ThreadObject,
            "FA_Thread_Hook", &thread_hook,
            "FA_Thread_Name", "test.thread",
            "FA_Thread_Priority", "Low",
            End;
        if (thread)
        {
            IDOS_ Printf
            (
                "Thread 0x%08lx - Priority %ld.\n" \
                "Use Ctrl-C to terminate the demo.\n",
                (int32) thread, IFEELIN F_Get(thread, (uint32) "Priority")
            );
            IEXEC Wait(SIGBREAKF_CTRL_C);
            IFEELIN F_DisposeObj(thread);
        }
        F_FEELIN_CLOSE;
    }
    return 0;
}
Thread's name.
Default is "New Process".
Thread's priority, which is Normal by default.
Valid priorities range from -127 to 128. You can also use one of the following predefined priorities.
FV_Thread_Priority_Idle FV_Thread_Priority_Low FV_Thread_Priority_Normal FV_Thread_Priority_High
Thread's process.
IFEELIN F_Do(Obj, FM_Thread_Send, uint32 Cmd,...);
Use this function to send a message to your thread and wait for a reply.
Id of the command to send. Note that some values such as FV_Thread_Hello and FV_Thread_Bye are reserved, you must start yours from FV_Thread_Dummy.
The parameters attached to your command.
The return value is command specific.