Changeset 012dd8e in mainline


Ignore:
Timestamp:
2019-08-07T09:15:30Z (5 years ago)
Author:
Matthieu Riolo <matthieu.riolo@…>
Children:
e8747bd8
Parents:
780c8ce
git-author:
Michal Koutný <xm.koutny+hos@…> (2015-11-01 00:08:04)
git-committer:
Matthieu Riolo <matthieu.riolo@…> (2019-08-07 09:15:30)
Message:

taskman: Handle INIT_TASKS as tasks spawned by loader

  • everyone is connected to its spawner, except for INIT_TASKS, they are connected to taskman (first binary)
  • taskman is now aware even of INIT_TASKS and taskman itself
  • refactored taskman handshake — NS session is created lazily
  • refactored async.c with usage of create_session
  • changed EINVAL to EINTR on lost waits
  • removed TODOs from taskman and related libc TODOs

Conflicts:

abi/include/abi/ipc/methods.h
boot/Makefile.common
uspace/lib/c/generic/async.c
uspace/lib/c/generic/libc.c
uspace/lib/c/generic/loader.c
uspace/lib/c/generic/ns.c
uspace/lib/c/generic/private/async.h
uspace/lib/c/generic/private/taskman.h
uspace/lib/c/generic/task.c
uspace/lib/c/include/async.h
uspace/lib/c/include/task.h
uspace/srv/loader/main.c
uspace/srv/ns/ns.c

Files:
29 edited
1 moved

Legend:

Unmodified
Added
Removed
  • abi/include/abi/ipc/methods.h

    r780c8ce r012dd8e  
    3838#include <abi/cap.h>
    3939
    40 /* Well known phone descriptors */
    41 static cap_phone_handle_t const PHONE_INITIAL = (cap_phone_handle_t) (CAP_NIL + 1);
    42 
    4340/** Kernel IPC interfaces
    4441 *
  • boot/Makefile.common

    r780c8ce r012dd8e  
    6868INITRD = initrd
    6969
    70 # NOTE: Naming service must be first task in the list
     70# NOTE: Order of tasks here is important since kernel connects initial phone of
     71# all these tasks to answerbox of the first one in this list (its phone is left
     72# untouched).
     73# INIT_TASKS = \
     74#       $(USPACE_PATH)/srv/taskman/taskman \
     75#       $(USPACE_PATH)/srv/ns/ns \
     76#       $(USPACE_PATH)/srv/locsrv/locsrv \
     77#       $(USPACE_PATH)/srv/vfs/vfs \
     78#       $(USPACE_PATH)/srv/loader/loader \
     79#       $(USPACE_PATH)/srv/bd/rd/rd
     80
    7181INIT_TASKS = \
     82        $(USPACE_PATH)/srv/taskman/taskman \
    7283        $(USPACE_PATH)/srv/ns/ns \
     84        $(USPACE_PATH)/srv/locsrv/locsrv \
     85        $(USPACE_PATH)/srv/vfs/vfs \
     86        $(USPACE_PATH)/srv/sysman/sysman \
    7387        $(USPACE_PATH)/srv/loader/loader \
    74         $(USPACE_PATH)/srv/sysman/sysman \
    75         $(USPACE_PATH)/srv/locsrv/locsrv \
    76         $(USPACE_PATH)/srv/bd/rd/rd \
    77         $(USPACE_PATH)/srv/vfs/vfs \
    7888        $(USPACE_PATH)/srv/logger/logger \
    79         $(USPACE_PATH)/srv/taskman/taskman
     89        $(USPACE_PATH)/srv/bd/rd/rd
     90
    8091
    8192ifeq ($(RDFMT),tmpfs)
  • kernel/generic/src/main/kinit.c

    r780c8ce r012dd8e  
    211211        }
    212212
     213        /*
     214         * Initialize and prepare init tasks for start.
     215         *
     216         * All tasks' phone no 0 is connected to answerbox of the first of the
     217         * init tasks (except for the first task itself).
     218         */
    213219        for (i = 0; i < init.cnt; i++) {
    214220                if (init.tasks[i].paddr % FRAME_SIZE) {
  • uspace/app/tester/proc/task_wait.c

    r780c8ce r012dd8e  
    7373        rc = task_wait(&wait, &texit, &retval);
    7474        TPRINTF("done.\n");
    75         TASSERT(rc == EINVAL);
     75        TASSERT(rc == EINTR);
    7676        TASSERT(task_wait_get(&wait) == 0);
    7777        TPRINTF("OK\n");
     
    215215        rc = task_wait(&wait, &texit, &retval);
    216216        TPRINTF("done.\n");
    217         TASSERT(rc == EINVAL);
     217        TASSERT(rc == EINTR);
    218218        TASSERT(task_wait_get(&wait) == 0);
    219219        TASSERT(texit == TASK_EXIT_UNEXPECTED);
  • uspace/lib/c/generic/async/client.c

    r780c8ce r012dd8e  
    124124static fibril_rmutex_t message_mutex;
    125125
    126 /** Primary session (spawn parent, later naming service) */
    127 async_sess_t *session_primary = NULL;
    128 
    129126/** Message data */
    130127typedef struct {
     
    169166
    170167
    171 static async_sess_t *create_session_primary(void)
     168/** Create session for existing phone
     169 *
     170 * @return session on success, NULL on error
     171 */
     172 
     173async_sess_t *create_session(cap_phone_handle_t phone, exch_mgmt_t mgmt,
     174    sysarg_t arg1, sysarg_t arg2, sysarg_t arg3)
    172175{
    173176        async_sess_t *session = (async_sess_t *) malloc(sizeof(async_sess_t));
    174177
    175178        if (session != NULL) {
    176                 // TODO extract common part with async_connect_me_to
    177                 session_ns->iface = 0;
    178                 session->mgmt = EXCHANGE_ATOMIC;
    179                 session->phone = PHONE_INITIAL;
    180                 session->arg1 = 0;
    181                 session->arg2 = 0;
    182                 session->arg3 = 0;
     179                session->iface = 0;
     180                session->mgmt = mgmt;
     181                session->phone = phone;
     182                session->arg1 = arg1;
     183                session->arg2 = arg2;
     184                session->arg3 = arg3;
    183185               
    184186                fibril_mutex_initialize(&session->remote_state_mtx);
     
    189191                atomic_set(&session->refcnt, 0);
    190192                &session.exchanges = 0;
     193        } else {
     194                errno = ENOMEM;
    191195        }
    192196
     
    196200
    197201/** Initialize the async framework.
    198  * @param arg_session_primary Primary session (to naming service).
    199  *
    200  */
    201 void __async_client_init(async_sess_t *arg_session_primary)
     202 *
     203 */
     204void __async_client_init(void)
    202205{
    203206        if (fibril_rmutex_initialize(&message_mutex) != EOK)
    204                 abort();
    205 
    206         if (arg_session_primary == NULL) {
    207                 session_primary = create_session_primary();
    208         } else {
    209                 session_primary = arg_session_primary;
    210         }
    211 
    212         if (session_primary == NULL)
    213207                abort();
    214208}
     
    832826}
    833827
    834 /** Injects another session instead of original primary session
    835  *
    836  * @param  session  Session to naming service.
    837  *
    838  * @return old primary session (to spawn parent)
    839  */
    840 async_sess_t *async_session_primary_swap(async_sess_t *session)
    841 {
    842         assert(session_primary->phone == PHONE_INITIAL);
    843 
    844         async_sess_t *old_primary = session_primary;
    845         session_primary = session;
    846         return old_primary;
    847 }
    848 
    849828/** Wrapper for making IPC_M_CONNECT_ME_TO calls using the async framework.
    850829 *
     
    865844        if (exch == NULL) {
    866845                errno = ENOENT;
    867                 return NULL;
    868         }
    869 
    870         async_sess_t *sess = calloc(1, sizeof(async_sess_t));
    871         if (sess == NULL) {
    872                 errno = ENOMEM;
    873846                return NULL;
    874847        }
     
    879852        if (rc != EOK) {
    880853                errno = rc;
    881                 free(sess);
    882854                return NULL;
    883855        }
    884856
    885         sess->iface = iface;
    886         sess->phone = phone;
    887         sess->arg1 = iface;
    888         sess->arg2 = arg2;
    889         sess->arg3 = arg3;
    890 
    891         fibril_mutex_initialize(&sess->remote_state_mtx);
    892         list_initialize(&sess->exch_list);
    893         fibril_mutex_initialize(&sess->mutex);
     857        async_sess_t *sess = create_session(phone, mgmt, iface, arg2, arg3);
     858        if (sess == NULL) {
     859                ipc_hangup(phone);
     860        }
    894861
    895862        return sess;
     
    933900        if (exch == NULL) {
    934901                errno = ENOENT;
    935                 return NULL;
    936         }
    937 
    938         async_sess_t *sess = calloc(1, sizeof(async_sess_t));
    939         if (sess == NULL) {
    940                 errno = ENOMEM;
    941902                return NULL;
    942903        }
     
    951912        }
    952913
    953         sess->iface = iface;
    954         sess->phone = phone;
    955         sess->arg1 = iface;
    956         sess->arg2 = arg2;
    957         sess->arg3 = arg3;
    958 
    959         fibril_mutex_initialize(&sess->remote_state_mtx);
    960         list_initialize(&sess->exch_list);
    961         fibril_mutex_initialize(&sess->mutex);
     914        async_sess_t *sess = create_session(phone, mgmt, iface, arg2, arg3);
     915        if (sess == NULL) {
     916                ipc_hangup(phone);
     917        }
    962918
    963919        return sess;
     
    969925async_sess_t *async_connect_kbox(task_id_t id)
    970926{
    971         async_sess_t *sess = calloc(1, sizeof(async_sess_t));
    972         if (sess == NULL) {
    973                 errno = ENOMEM;
    974                 return NULL;
    975         }
    976 
    977927        cap_phone_handle_t phone;
    978928        errno_t rc = ipc_connect_kbox(id, &phone);
    979929        if (rc != EOK) {
    980930                errno = rc;
    981                 free(sess);
    982931                return NULL;
    983932        }
    984933
    985         sess->iface = 0;
    986         sess->mgmt = EXCHANGE_ATOMIC;
    987         sess->phone = phone;
    988 
    989         fibril_mutex_initialize(&sess->remote_state_mtx);
    990         list_initialize(&sess->exch_list);
    991         fibril_mutex_initialize(&sess->mutex);
     934        async_sess_t *sess = create_session(phone, EXCHANGE_ATOMIC, 0, 0, 0);
     935        if (sess == NULL) {
     936                ipc_hangup(phone);
     937        }
    992938
    993939        return sess;
  • uspace/lib/c/generic/async/server.c

    r780c8ce r012dd8e  
    391391 *                    calls routed through that phone.
    392392 * @param in_task_id  Identification of the incoming connection.
    393  * @param call        Call data of the opening call. If call is NULL, the
    394  *                    connection was opened by accepting the
    395  *                    IPC_M_CONNECT_TO_ME call and this function is called
    396  *                    directly by the server.
     393 * @param call        Call data of the opening call. If call is NULL, it's
     394 *                    either a callback connection that was opened by
     395 *                    accepting the IPC_M_CONNECT_TO_ME call.
     396 *                    Alternatively, it is zero when we are opening
     397 *                    implicit connection.
    397398 * @param handler     Connection handler.
    398399 * @param data        Client argument to pass to the connection handler.
     
    17461747        }
    17471748
    1748         async_sess_t *sess = calloc(1, sizeof(async_sess_t));
     1749        async_sess_t *sess = create_session(phandle, mgmt, 0, 0, 0);
    17491750        if (sess == NULL) {
    1750                 async_answer_0(&call, ENOMEM);
    1751                 return NULL;
    1752         }
    1753 
    1754         sess->iface = 0;
    1755         sess->mgmt = mgmt;
    1756         sess->phone = phandle;
    1757 
    1758         fibril_mutex_initialize(&sess->remote_state_mtx);
    1759         list_initialize(&sess->exch_list);
    1760         fibril_mutex_initialize(&sess->mutex);
    1761 
    1762         /* Acknowledge the connected phone */
    1763         async_answer_0(&call, EOK);
     1751                ipc_hangup(phone);
     1752                async_answer_0(&call, errno);
     1753        } else {
     1754                /* Acknowledge the connected phone */
     1755                async_answer_0(&call, EOK);
     1756        }
    17641757
    17651758        return sess;
     
    17881781                return NULL;
    17891782
    1790         async_sess_t *sess = calloc(1, sizeof(async_sess_t));
    1791         if (sess == NULL)
    1792                 return NULL;
    1793 
    1794         sess->iface = 0;
    1795         sess->mgmt = mgmt;
    1796         sess->phone = phandle;
    1797 
    1798         fibril_mutex_initialize(&sess->remote_state_mtx);
    1799         list_initialize(&sess->exch_list);
    1800         fibril_mutex_initialize(&sess->mutex);
    1801 
    1802         return sess;
     1783        return create_session(phandle, mgmt, 0, 0, 0);
    18031784}
    18041785
  • uspace/lib/c/generic/libc.c

    r780c8ce r012dd8e  
    5151#include "private/fibril.h"
    5252#include "private/malloc.h"
    53 #include "private/ns.h" // TODO maybe better filename for session_primary
    5453#include "private/task.h"
     54#include "private/taskman.h"
    5555
    5656
     
    6363static bool env_setup;
    6464static fibril_t main_fibril;
     65
     66static void initialize_taskman(pcb_t *pcb)
     67{
     68        if (__pcb == NULL) {
     69                async_sess_t *session_tm = taskman_connect();
     70                if (session_tm == NULL) {
     71                        abort();
     72                }
     73                __task_init(session_tm);
     74        } else {
     75                __task_init(__pcb->session_taskman);
     76        }
     77}
    6578
    6679void __libc_main(void *pcb_ptr)
     
    107120#endif
    108121       
    109         /* Setup async framework */
     122        /* Setup async framework and taskman connection */
    110123        __async_server_init();
    111         if (__pcb == NULL) {
    112                 __async_client_init(NULL);
    113                 __task_init(NULL);
    114         } else {
    115                 __async_client_init(__pcb->session_primary);
    116                 __task_init(__pcb->session_taskman);
    117         }
     124        __async_client_init();
    118125        __async_ports_init();
     126        initialize_taskman(__pcb);
    119127
    120128        /* The basic run-time environment is setup */
  • uspace/lib/c/generic/loader.c

    r780c8ce r012dd8e  
    4545#include <task.h>
    4646#include <vfs/vfs.h>
     47
    4748#include "private/loader.h"
     49#include "private/taskman.h"
    4850
    4951/** Connect to a new program loader.
     
    6668        if (ldr == NULL)
    6769                return NULL;
    68 
    69         async_sess_t *sess =
    70             service_connect_blocking(SERVICE_TASKMAN, TASKMAN_CONNECT_TO_LOADER, 0);
     70       
     71        async_sess_t *sess = taskman_session_loader();
    7172        if (sess == NULL) {
    7273                free(ldr);
  • uspace/lib/c/generic/ns.c

    r780c8ce r012dd8e  
    3838#include <macros.h>
    3939#include <errno.h>
    40 #include "private/ns.h"
     40
     41#include "private/taskman.h"
     42
     43static async_sess_t *session_ns = NULL;
     44
     45static async_exch_t *ns_exchange_begin(void)
     46{
     47        /* Lazily connect to our NS */
     48        if (session_ns == NULL) {
     49                session_ns = taskman_session_ns();
     50        }
     51
     52        async_exch_t *exch = async_exchange_begin(session_ns);
     53        return exch;
     54}
     55
     56static void ns_exchange_end(async_exch_t *exch)
     57{
     58        async_exchange_end(exch);
     59}
    4160
    4261/*
     
    4968    async_port_handler_t handler, void *data)
    5069{
    51         async_sess_t *sess = get_session_primary();
    52         if (sess == NULL)
    53                 return EIO;
    54 
    5570        port_id_t port;
    5671        errno_t rc = async_create_port(iface, handler, data, &port);
     
    5873                return rc;
    5974
    60         async_exch_t *exch = async_exchange_begin(sess);
     75        async_exch_t *exch = ns_exchange_begin();
    6176
    6277        ipc_call_t answer;
     
    6479        rc = async_connect_to_me(exch, iface, service, 0);
    6580
    66         async_exchange_end(exch);
     81        ns_exchange_end(exch);
    6782
    6883        if (rc != EOK) {
     
    105120async_sess_t *service_connect(service_t service, iface_t iface, sysarg_t arg3)
    106121{
    107         async_sess_t *sess = get_session_primary();
    108         if (sess == NULL)
    109                 return NULL;
    110 
    111         async_exch_t *exch = async_exchange_begin(sess);
     122        async_exch_t *exch = ns_exchange_begin();
    112123        if (exch == NULL)
    113124                return NULL;
    114125
    115         async_sess_t *csess =
     126        async_sess_t *sess =
    116127            async_connect_me_to(exch, iface, service, arg3);
    117         async_exchange_end(exch);
     128        ns_exchange_end(exch);
    118129
    119         if (csess == NULL)
     130        if (sess == NULL)
    120131                return NULL;
    121132
     
    125136         * first argument for non-initial connections.
    126137         */
    127         async_sess_args_set(csess, iface, arg3, 0);
     138        async_sess_args_set(sess, iface, arg3, 0);
    128139
    129140        return csess;
     
    133144    sysarg_t arg3)
    134145{
    135         async_sess_t *sess = get_session_primary();
     146        async_exch_t *exch = ns_exchange_begin();
     147        async_sess_t *sess =
     148            async_connect_me_to_blocking(exch, iface, service, arg3);
     149        ns_exchange_end(exch);
     150
    136151        if (sess == NULL)
    137                 return NULL;
    138 
    139         async_exch_t *exch = async_exchange_begin(sess);
    140         async_sess_t *csess =
    141             async_connect_me_to_blocking(exch, iface, service, arg3);
    142         async_exchange_end(exch);
    143 
    144         if (csess == NULL)
    145152                return NULL;
    146153
     
    150157         * first argument for non-initial connections.
    151158         */
    152         async_sess_args_set(csess, iface, arg3, 0);
     159        async_sess_args_set(sess, iface, arg3, 0);
    153160
    154         return csess;
     161        return sess;
    155162}
    156163
    157164errno_t ns_ping(void)
    158165{
    159         async_sess_t *sess = get_session_primary();
    160         if (sess == NULL)
    161                 return EIO;
    162 
    163         async_exch_t *exch = async_exchange_begin(sess);
     166        async_exch_t *exch = ns_exchange_begin(sess);
    164167        errno_t rc = async_req_0_0(exch, NS_PING);
    165         async_exchange_end(exch);
     168        ns_exchange_end(exch);
    166169
    167170        return rc;
    168171}
    169172
    170 
    171 async_sess_t *get_session_primary(void)
    172 {
    173         async_exch_t *exch;
    174 
    175         if (sess_primary == NULL) {
    176                 exch = async_exchange_begin(&session_primary);
    177                 sess_primary = async_connect_me_to(exch, 0, 0, 0);
    178                 async_exchange_end(exch);
    179                 if (sess_primary == NULL)
    180                         return NULL;
    181         }
    182 
    183         return sess_primary;
    184 }
    185 
    186173/** @}
    187174 */
  • uspace/lib/c/generic/private/async.h

    r780c8ce r012dd8e  
    9696extern void __async_server_init(void);
    9797extern void __async_server_fini(void);
    98 extern void __async_client_init(async_sess_t *);
     98extern void __async_client_init(void);
    9999extern void __async_client_fini(void);
    100100extern void __async_ports_init(void);
     
    106106
    107107extern void async_reply_received(ipc_call_t *);
     108extern async_sess_t *create_session(int, exch_mgmt_t,
     109        sysarg_t, sysarg_t, sysarg_t);
    108110
    109111#endif
  • uspace/lib/c/generic/private/task.h

    r780c8ce r012dd8e  
    3636#define LIBC_PRIVATE_TASK_H_
    3737
    38 #include <async.h>
    39 
    40 void __task_init(async_sess_t *);
    41 
    4238int task_retval_internal(int, bool);
    43 
    44 async_exch_t *taskman_exchange_begin(void);
    45 
    46 void taskman_exchange_end(async_exch_t *);
    4739
    4840#endif
  • uspace/lib/c/generic/private/taskman.h

    r780c8ce r012dd8e  
    11/*
    2  * Copyright (c) 2011 Martin Decky
     2 * Copyright (c) 2015 Michal Koutny
    33 * All rights reserved.
    44 *
     
    3333 */
    3434
    35 #ifndef _LIBC_PRIVATE_NS_H_
    36 #define _LIBC_PRIVATE_NS_H_
     35#ifndef LIBC_PRIVATE_TASKMAN_H_
     36#define LIBC_PRIVATE_TASKMAN_H_
    3737
    3838#include <async.h>
    3939
    40 extern async_sess_t *session_primary;
     40extern async_sess_t *session_taskman;
     41
     42void __task_init(async_sess_t *);
     43
     44async_exch_t *taskman_exchange_begin(void);
     45void taskman_exchange_end(async_exch_t *);
     46
     47extern async_sess_t *taskman_connect(void);
     48extern async_sess_t *taskman_session_ns(void);
     49extern async_sess_t *taskman_session_loader(void);
    4150
    4251#endif
  • uspace/lib/c/generic/task.c

    r780c8ce r012dd8e  
    4949#include <str.h>
    5050#include <task.h>
     51#include <taskman.h>
    5152#include <vfs/vfs.h>
    52 #include "private/ns.h"
     53
    5354#include "private/task.h"
    54 
    55 static async_sess_t *session_taskman = NULL;
     55#include "private/taskman.h"
    5656
    5757task_id_t task_get_id(void)
     
    6969}
    7070
    71 async_exch_t *taskman_exchange_begin(void)
    72 {
    73         /* Lazy connection */
    74         if (session_taskman == NULL) {
    75                 // TODO unify exchange mgmt with taskman_handshake/__init
    76                 session_taskman = service_connect_blocking(EXCHANGE_SERIALIZE,
    77                     SERVICE_TASKMAN,
    78                     TASKMAN_CONTROL,
    79                     0);
    80         }
    81 
    82         if (session_taskman == NULL) {
    83                 return NULL;
    84         }
    85 
    86         async_exch_t *exch = async_exchange_begin(session_taskman);
    87         return exch;
    88 }
    89 
    90 void taskman_exchange_end(async_exch_t *exch)
    91 {
    92         async_exchange_end(exch);
    93 }
    94 
    9571/** Set the task name.
    9672 *
     
    129105 *
    130106 * @return EOK on success, else error code.
    131  * @return TODO check this doesn't return EINVAL -- clash with task_wait
    132107 */
    133108static errno_t task_setup_wait(task_id_t id, task_wait_t *wait)
     
    393368 * (it can be reused, but must be reinitialized with task_setup_wait first)
    394369 *
    395  * @param wait   task_wait_t previously initialized by task_setup_wait.
    396  * @param texit  Store type of task exit here.
    397  * @param retval Store return value of the task here.
     370 * @param[in/out] wait   task_wait_t previously initialized by task_setup_wait
     371 *                       or returned by task_wait with non-zero flags. the
     372 *                       flags are updated so that they represent what can be
     373 *                       still waited for.
     374 * @param[out]    texit  Store type of task exit here.
     375 * @param[out]    retval Store return value of the task here.
    398376 *
    399377 * @return EOK on success
    400  * @return EINVAL on lost wait TODO other error codes
     378 * @return EINTR on lost wait
    401379 */
    402380errno_t task_wait(task_wait_t *wait, task_exit_t *texit, int *retval)
     
    405383        async_wait_for(wait->aid, &rc);
    406384
    407         if (rc == EOK || rc == EINVAL) {
     385        if (rc == EOK || rc == EINTR) {
    408386                if (wait->flags & TASK_WAIT_EXIT && texit)
    409387                        *texit = ipc_get_arg1(wait->result);
     
    471449}
    472450
    473 void __task_init(async_sess_t *sess)
    474 {
    475         assert(session_taskman == NULL);
    476         session_taskman = sess;
    477 }
    478 
    479451/** @}
    480452 */
  • uspace/lib/c/generic/task_event.c

    r780c8ce r012dd8e  
    3838#include <task.h>
    3939
    40 #include "private/task.h"
     40#include "private/taskman.h"
    4141
    4242static task_event_handler_t task_event_handler = NULL;
     
    6565
    6666                if (!IPC_GET_IMETHOD(call)) {
    67                         /* Hangup, TODO explain or handle differntly */
     67                        /* Hangup, end of game */
    6868                        break;
    6969                }
  • uspace/lib/c/generic/taskman.c

    r780c8ce r012dd8e  
    3333 */
    3434
     35
     36#include <async.h>
    3537#include <errno.h>
     38#include <ipc/common.h>
    3639#include <ipc/taskman.h>
     40#include <task.h>
    3741#include <taskman.h>
    3842
    39 #include <stdio.h>
     43#include "private/async.h"
     44#include "private/taskman.h"
    4045
    41 //TODO better filename?
    42 #include "private/ns.h"
     46async_sess_t *session_taskman = NULL;
    4347
    44 static int taskman_ask_callback(async_sess_t *session_tm)
     48void __task_init(async_sess_t *sess)
    4549{
    46         async_exch_t *exch = async_exchange_begin(session_tm);
     50        assert(session_taskman == NULL);
     51        session_taskman = sess;
     52}
     53
     54async_exch_t *taskman_exchange_begin(void)
     55{
     56        assert(session_taskman);
     57
     58        async_exch_t *exch = async_exchange_begin(session_taskman);
     59        return exch;
     60}
     61
     62void taskman_exchange_end(async_exch_t *exch)
     63{
     64        async_exchange_end(exch);
     65}
     66
     67/** Wrap PHONE_INITIAL with session and introduce to taskman
     68 */
     69async_sess_t *taskman_connect(void)
     70{
     71        /*
     72         *  EXCHANGE_ATOMIC would require single calls only,
     73         *  EXCHANGE_PARALLEL not sure about implementation via multiple phones,
     74         * >EXCHANGE_SERIALIZE perhaphs no harm, except the client serialization
     75         */
     76        const exch_mgmt_t mgmt = EXCHANGE_SERIALIZE;
     77        async_sess_t *sess = create_session(PHONE_INITIAL, mgmt, 0, 0, 0);
     78
     79        if (sess != NULL) {
     80                /* Introduce ourselves and ignore answer */
     81                async_exch_t *exch = async_exchange_begin(sess);
     82                aid_t req = async_send_0(exch, TASKMAN_NEW_TASK, NULL);
     83                async_exchange_end(exch);
     84               
     85                if (req) {
     86                        async_forget(req);
     87                }
     88        }
     89
     90        return sess;
     91}
     92
     93/** Ask taskman to pass/share its NS */
     94async_sess_t *taskman_session_ns(void)
     95{
     96        assert(session_taskman);
     97
     98        async_exch_t *exch = async_exchange_begin(session_taskman);
     99        assert(exch);
     100
     101        async_sess_t *sess = async_connect_me_to(EXCHANGE_ATOMIC,
     102            exch, TASKMAN_CONNECT_TO_NS, 0, 0);
     103        async_exchange_end(exch);
     104
     105        return sess;
     106}
     107
     108/** Ask taskman to connect to (a new) loader instance */
     109async_sess_t *taskman_session_loader(void)
     110{
     111        assert(session_taskman);
     112
     113        async_exch_t *exch = async_exchange_begin(session_taskman);
     114        async_sess_t *sess = async_connect_me_to(EXCHANGE_SERIALIZE,
     115            exch, TASKMAN_CONNECT_TO_LOADER, 0, 0);
     116        async_exchange_end(exch);
     117
     118        return sess;
     119}
     120
     121/** Introduce as loader to taskman
     122 *
     123 * @return EOK on success, otherwise propagated error code
     124 */
     125int taskman_intro_loader(void)
     126{
     127        assert(session_taskman);
     128
     129        async_exch_t *exch = async_exchange_begin(session_taskman);
    47130        int rc = async_connect_to_me(
    48131            exch, TASKMAN_LOADER_CALLBACK, 0, 0, NULL, NULL);
     
    52135}
    53136
    54 static async_sess_t *taskman_connect_to_ns(async_sess_t *session_tm)
     137/** Tell taskman we are his NS
     138 *
     139 * @return EOK on success, otherwise propagated error code
     140 */
     141int taskman_intro_ns(void)
    55142{
    56         async_exch_t *exch = async_exchange_begin(session_tm);
    57         async_sess_t *session_ns = async_connect_me_to(EXCHANGE_ATOMIC,
    58             exch, TASKMAN_LOADER_TO_NS, 0, 0);
    59         async_exchange_end(exch);
     143        assert(session_taskman);
    60144
    61         return session_ns;
     145        async_exch_t *exch = async_exchange_begin(session_taskman);
     146        aid_t req = async_send_0(exch, TASKMAN_I_AM_NS, NULL);
     147
     148        int rc = async_connect_to_me(exch, 0, 0, 0, NULL, NULL);
     149        taskman_exchange_end(exch);
     150
     151        if (rc != EOK) {
     152                return rc;
     153        }
     154
     155        sysarg_t retval;
     156        async_wait_for(req, &retval);
     157        return retval;
    62158}
    63159
    64 /** Set up phones upon being spawned by taskman
    65  *
    66  * Assumes primary session exists that is connected to taskman.
    67  * After handshake, taskman is connected to us (see, it's opposite) and broker
    68  * session is set up according to taskman.
    69  *
    70  *
    71  * @return Session to broker (naming service) or NULL (sets errno).
    72  */
    73 async_sess_t *taskman_handshake(void)
     160async_sess_t *taskman_get_session(void)
    74161{
    75         int rc = taskman_ask_callback(session_primary);
    76         if (rc != EOK) {
    77                 errno = rc;
    78                 return NULL;
    79         }
     162        return session_taskman;
     163}
    80164
    81         async_sess_t *session_ns = taskman_connect_to_ns(session_primary);
    82         if (session_ns == NULL) {
    83                 errno = ENOENT;
    84         }
    85165
    86         return session_ns;
    87 }
    88166
    89167/** @}
  • uspace/lib/c/include/async.h

    r780c8ce r012dd8e  
    276276extern sysarg_t async_get_label(void);
    277277
    278 extern async_sess_t *async_session_primary_swap(async_sess_t *);
    279278extern async_sess_t *async_connect_me_to(async_exch_t *, iface_t, sysarg_t,
    280279    sysarg_t);
  • uspace/lib/c/include/ipc/common.h

    r780c8ce r012dd8e  
    3939#include <abi/ipc/ipc.h>
    4040
     41/* Well known phone descriptors */
     42#define PHONE_INITIAL  0
     43
    4144#define IPC_FLAG_BLOCKING   0x01
    4245// TODO autostart flag may be united with blocking, this should be later made
  • uspace/lib/c/include/ipc/services.h

    r780c8ce r012dd8e  
    4646        SERVICE_LOC        = FOURCC('l', 'o', 'c', ' '),
    4747        SERVICE_SYSMAN     = FOURCC('s', 'y', 's', 'm'),
    48         SERVICE_TASKMAN    = FOURCC('t', 's', 'k', 'm'),
    4948        SERVICE_LOGGER     = FOURCC('l', 'o', 'g', 'g'),
    5049        SERVICE_DEVMAN     = FOURCC('d', 'e', 'v', 'n'),
  • uspace/lib/c/include/ipc/taskman.h

    r780c8ce r012dd8e  
    4242        TASKMAN_WAIT = IPC_FIRST_USER_METHOD,
    4343        TASKMAN_RETVAL,
    44         TASKMAN_EVENT_CALLBACK
     44        TASKMAN_EVENT_CALLBACK,
     45        TASKMAN_NEW_TASK,
     46        TASKMAN_I_AM_NS
    4547} taskman_request_t;
    4648
     
    5052
    5153typedef enum {
    52         TASKMAN_CONNECT_TO_LOADER = 0,
    53         TASKMAN_LOADER_TO_NS,
    54         TASKMAN_LOADER_CALLBACK,
    55         TASKMAN_CONTROL
    56 } taskman_interface_t;
     54        TASKMAN_CONNECT_TO_NS = 0,
     55        TASKMAN_CONNECT_TO_LOADER,
     56        TASKMAN_LOADER_CALLBACK
     57} taskman_connect_t;
    5758
    5859#endif
  • uspace/lib/c/include/loader/pcb.h

    r780c8ce r012dd8e  
    6161        entry_point_t entry;
    6262
    63         /** Primary session to broker. */
    64         async_sess_t *session_primary;
    65        
    6663        /** Session to taskman (typically spawn parent) */
    6764        async_sess_t *session_taskman;
  • uspace/lib/c/include/ns.h

    r780c8ce r012dd8e  
    4949extern async_sess_t *ns_session_get(void);
    5050
     51extern async_sess_t *ns_get_session(void);
     52
    5153#endif
    5254
  • uspace/lib/c/include/task.h

    r780c8ce r012dd8e  
    7676extern errno_t task_retval(int);
    7777
    78 /* Implemented in task_event.h */
     78/* Implemented in task_event.c */
    7979extern int task_register_event_handler(task_event_handler_t);
    8080
  • uspace/lib/c/include/taskman.h

    r780c8ce r012dd8e  
    3636#define LIBC_TASKMAN_H_
    3737
     38#ifndef TASKMAN_DISABLE_ASYNC
    3839#include <async.h>
     40#endif
    3941
    40 extern async_sess_t *taskman_handshake(void);
     42/* Internal functions to be used by loader only */
     43#ifndef TASKMAN_DISABLE_ASYNC
     44extern async_sess_t *taskman_get_session(void);
     45#endif
     46extern int taskman_intro_loader(void);
     47
     48/* Internal functions to be used by NS only */
     49extern int taskman_intro_ns(void);
    4150
    4251#endif
  • uspace/srv/loader/main.c

    r780c8ce r012dd8e  
    3535 * The program loader is a special init binary. Its image is used
    3636 * to create a new task upon a @c task_spawn syscall. It has a phone connected
    37  * to the caller of te syscall. The formal caller (taskman) performs a
     37 * to the caller of the syscall. The formal caller (taskman) performs a
    3838 * handshake with loader so that apparent caller can communicate with the
    3939 * loader.
     
    6060#include <ipc/loader.h>
    6161#include <loader/pcb.h>
     62#include <ns.h>
    6263#include <str.h>
    6364#include <sys/types.h>
     65#include <task.h>
    6466#include <taskman.h>
    6567#include <unistd.h>
     
    7274#endif
    7375
     76#define NAME "loader"
    7477#define DPRINTF(...) ((void) 0)
    7578
     
    8083/** The Program control block */
    8184static pcb_t pcb;
    82 
    83 /** Primary IPC session */
    84 static async_sess_t *session_primary = NULL;
    85 
    86 /** Session to taskman (typically our spawner) */
    87 static async_sess_t *session_taskman = NULL;
    8885
    8986/** Current working directory */
     
    105102/** Used to limit number of connections to one. */
    106103static bool connected = false;
    107 
    108 /** Ensure synchronization of handshake and connection fibrils. */
    109 static bool handshake_complete = false;
    110 FIBRIL_MUTEX_INITIALIZE(handshake_mtx);
    111 FIBRIL_CONDVAR_INITIALIZE(handshake_cv);
    112104
    113105static void ldr_get_taskid(ipc_call_t *req)
     
    337329        DPRINTF("PCB set.\n");
    338330
    339         pcb.session_primary = session_primary;
    340         pcb.session_taskman = session_taskman;
     331        pcb.session_taskman = taskman_get_session();
    341332
    342333        pcb.cwd = cwd;
     
    394385static void ldr_connection(ipc_call_t *icall, void *arg)
    395386{
    396         /* Wait for handshake */
    397         fibril_mutex_lock(&handshake_mtx);
    398         while (!handshake_complete) {
    399                 fibril_condvar_wait(&handshake_cv, &handshake_mtx);
    400         }
    401         fibril_mutex_unlock(&handshake_mtx);
    402 
    403387        /* Already have a connection? */
    404388        if (connected) {
     
    456440}
    457441
    458 /** Handshake with taskman
    459  *
    460  * Taskman is our spawn parent, i.e. PHONE_INITIAL is connected to it.
    461  * Goal of the handshake is to obtain phone to naming service and also keep the
    462  * session to taskman.
    463  *
    464  * @return EOK on success, for errors see taskman_handshake()
    465  */
    466 static errno_t ldr_taskman_handshake(void)
    467 {
    468         assert(session_primary == NULL);
    469         assert(session_taskman == NULL);
    470 
    471         errno_t retval = EOK;
    472 
    473         fibril_mutex_lock(&handshake_mtx);
    474         session_primary = taskman_handshake();
    475         if (session_primary == NULL) {
    476                 retval = errno;
    477                 goto finish;
    478         }
    479 
    480         session_taskman = async_session_primary_swap(session_primary);
    481 
    482         handshake_complete = true;
    483 
    484 finish:
    485         fibril_condvar_signal(&handshake_cv);
    486         fibril_mutex_unlock(&handshake_mtx);
    487 
    488         return retval;
    489 }
    490 
    491442/** Program loader main function.
    492443 */
     
    496447        async_set_fallback_port_handler(ldr_connection, NULL);
    497448       
    498         /* Handshake with taskman */
    499         int rc = ldr_taskman_handshake();
    500         if (rc != EOK) {
    501                 DPRINTF("Failed taskman handshake (%i).\n", errno);
     449        /* Announce to taskman. */
     450        errno_t rc = taskman_intro_loader();
     451        if (rc != EOK) {
     452                printf("%s: did not receive connectin from taskman (%i)\n",
     453                    NAME, rc);
    502454                return rc;
    503455        }
    504456
    505         /* Handle client connections */
     457        /*
     458         * We are not a regular server, thus no retval is set, just wait for
     459         * forwarded connections by taskman.
     460         */
    506461        async_manager();
    507         //TODO retval?
    508462       
    509463        /* Never reached */
  • uspace/srv/ns/ns.c

    r780c8ce r012dd8e  
    11/*
    22 * Copyright (c) 2006 Ondrej Palkovsky
     3 * Copyright (c) 2015 Michal Koutny
    34 * All rights reserved.
    45 *
     
    4344#include <stdio.h>
    4445#include <errno.h>
     46#define TASKMAN_DISABLE_ASYNC
     47#include <taskman.h>
     48#undef TASKMAN_DISABLE_ASYNC
     49
    4550#include "ns.h"
    4651#include "service.h"
     
    115120        if (rc != EOK)
    116121                return rc;
     122       
     123        rc = taskman_intro_ns();
     124        if (rc != EOK) {
     125                printf("%s: not accepted by taskman (%i)\n", NAME, rc);
     126                return rc;
     127        }
    117128
    118129        async_set_fallback_port_handler(ns_connection, NULL);
  • uspace/srv/sysman/main.c

    r780c8ce r012dd8e  
    229229        fibril_add_ready(event_loop_fibril);
    230230
     231        sysman_log(LVL_DEBUG, "Debugging pause...\n");
     232        async_usleep(10 * 1000000);
    231233        /* Queue first job from sequence */
    232234        prepare_and_run_job(&target_sequence[0]);
  • uspace/srv/taskman/event.c

    r780c8ce r012dd8e  
    137137                                /* Nothing to wait for anymore */
    138138                                if (answer) {
    139                                         async_answer_0(pr->callid, EINVAL);
     139                                        async_answer_0(pr->callid, EINTR);
    140140                                }
    141141                        } else {
     
    145145                } else if (answer) {
    146146                        if ((pr->flags & TASK_WAIT_BOTH) && match == TASK_WAIT_EXIT) {
    147                                 async_answer_1(pr->callid, EINVAL, t->exit);
     147                                /* No sense to wait for both anymore */
     148                                async_answer_1(pr->callid, EINTR, t->exit);
    148149                        } else {
    149150                                /* Send both exit status and retval, caller
     
    253254                pr->callid = callid;
    254255        }
    255         // TODO remove printf("%s: %llu: %x, %x, %i\n", __func__, pr->id, flags, pr->flags, reuse);
    256256
    257257finish:
  • uspace/srv/taskman/main.c

    r780c8ce r012dd8e  
    4141#include <async.h>
    4242#include <errno.h>
     43#include <fibril_synch.h>
    4344#include <ipc/services.h>
    4445#include <ipc/taskman.h>
     
    5354#include "taskman.h"
    5455
    55 //TODO move to appropriate header file
    56 extern async_sess_t *session_primary;
     56//#define DPRINTF(...) printf(__VA_ARGS__)
     57#define DPRINTF(...) /* empty */
    5758
    5859typedef struct {
     
    6364static prodcons_t sess_queue;
    6465
     66/** We keep session to NS on our own in taskman */
     67static async_sess_t *session_ns = NULL;
     68
     69static FIBRIL_MUTEX_INITIALIZE(session_ns_mtx);
     70static FIBRIL_CONDVAR_INITIALIZE(session_ns_cv);
    6571
    6672/*
     
    6975static void connect_to_loader(ipc_callid_t iid, ipc_call_t *icall)
    7076{
     77        DPRINTF("%s:%i from %llu\n", __func__, __LINE__, icall->in_task_id);
    7178        /* We don't accept the connection request, we forward it instead to
    7279         * freshly spawned loader. */
     
    7481       
    7582        if (rc != EOK) {
    76                 printf(NAME ": %s -> %i\n", __func__, rc);
    7783                async_answer_0(iid, rc);
    7884                return;
     
    9197        async_exchange_end(exch);
    9298
    93         /* After forward we can dispose all session-related resources
    94          * TODO later could be recycled for notification API
    95          */
     99        /* After forward we can dispose all session-related resources */
    96100        async_hangup(sess_ref->sess);
    97101        free(sess_ref);
     
    105109}
    106110
    107 static void loader_to_ns(ipc_callid_t iid, ipc_call_t *icall)
    108 {
    109         /* Do no accept connection request, forward it instead. */
    110         async_exch_t *exch = async_exchange_begin(session_primary);
     111static void connect_to_ns(ipc_callid_t iid, ipc_call_t *icall)
     112{
     113        DPRINTF("%s, %llu\n", __func__, icall->in_task_id);
     114
     115        /* Wait until we know NS */
     116        fibril_mutex_lock(&session_ns_mtx);
     117        while (session_ns == NULL) {
     118                fibril_condvar_wait(&session_ns_cv, &session_ns_mtx);
     119        }
     120        fibril_mutex_unlock(&session_ns_mtx);
     121
     122        /* Do not accept connection, forward it */
     123        async_exch_t *exch = async_exchange_begin(session_ns);
    111124        int rc = async_forward_fast(iid, exch, 0, 0, 0, IPC_FF_NONE);
    112125        async_exchange_end(exch);
     
    116129                return;
    117130        }
     131}
     132
     133static void taskman_new_task(ipc_callid_t iid, ipc_call_t *icall)
     134{
     135        int rc = task_intro(icall->in_task_id);
     136        async_answer_0(iid, rc);
     137}
     138
     139static void taskman_i_am_ns(ipc_callid_t iid, ipc_call_t *icall)
     140{
     141        DPRINTF("%s, %llu\n", __func__, icall->in_task_id);
     142        int rc = EOK;
     143
     144        fibril_mutex_lock(&session_ns_mtx);
     145        if (session_ns != NULL) {
     146                rc = EEXISTS;
     147                goto finish;
     148        }
     149
     150        /* Used only for connection forwarding -- atomic */
     151        session_ns = async_callback_receive(EXCHANGE_ATOMIC);
     152       
     153        if (session_ns == NULL) {
     154                rc = ENOENT;
     155                printf("%s: Cannot connect to NS\n", NAME);
     156        }
     157
     158        fibril_condvar_signal(&session_ns_cv);
     159finish:
     160        fibril_mutex_unlock(&session_ns_mtx);
     161        async_answer_0(iid, rc);
    118162}
    119163
     
    130174static void taskman_ctl_retval(ipc_callid_t iid, ipc_call_t *icall)
    131175{
    132         printf("%s:%i from %llu\n", __func__, __LINE__, icall->in_task_id);
    133176        task_id_t sender = icall->in_task_id;
    134177        int retval = IPC_GET_ARG1(*icall);
    135178        bool wait_for_exit = IPC_GET_ARG2(*icall);
    136179
     180        DPRINTF("%s:%i from %llu/%i\n", __func__, __LINE__, sender, retval);
     181
    137182        int rc = task_set_retval(sender, retval, wait_for_exit);
    138183        async_answer_0(iid, rc);
     
    141186static void taskman_ctl_ev_callback(ipc_callid_t iid, ipc_call_t *icall)
    142187{
    143         printf("%s:%i from %llu\n", __func__, __LINE__, icall->in_task_id);
     188        DPRINTF("%s:%i from %llu\n", __func__, __LINE__, icall->in_task_id);
     189
    144190        /* Atomic -- will be used for notifications only */
    145191        async_sess_t *sess = async_callback_receive(EXCHANGE_ATOMIC);
     
    157203        task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall));
    158204        exit_reason_t exit_reason = IPC_GET_ARG3(*icall);
    159         printf("%s:%i from %llu/%i\n", __func__, __LINE__, id, exit_reason);
     205        DPRINTF("%s:%i from %llu/%i\n", __func__, __LINE__, id, exit_reason);
    160206        task_terminated(id, exit_reason);
    161207}
     
    164210{
    165211        task_id_t id = MERGE_LOUP32(IPC_GET_ARG1(*icall), IPC_GET_ARG2(*icall));
    166         printf("%s:%i from %llu\n", __func__, __LINE__, id);
     212        DPRINTF("%s:%i from %llu\n", __func__, __LINE__, id);
    167213        task_failed(id);
    168214}
    169215
    170 static void control_connection_loop(void)
    171 {
    172         while (true) {
    173                 ipc_call_t call;
    174                 ipc_callid_t callid = async_get_call(&call);
    175 
    176                 if (!IPC_GET_IMETHOD(call)) {
    177                         /* Client disconnected */
    178                         break;
    179                 }
    180 
    181                 switch (IPC_GET_IMETHOD(call)) {
    182                 case TASKMAN_WAIT:
    183                         taskman_ctl_wait(callid, &call);
    184                         break;
    185                 case TASKMAN_RETVAL:
    186                         taskman_ctl_retval(callid, &call);
    187                         break;
    188                 case TASKMAN_EVENT_CALLBACK:
    189                         taskman_ctl_ev_callback(callid, &call);
    190                         break;
    191                 default:
    192                         async_answer_0(callid, ENOENT);
    193                 }
    194         }
    195 }
    196 
    197 static void control_connection(ipc_callid_t iid, ipc_call_t *icall)
    198 {
    199         /* TODO remove/redesign the workaround
    200          * Call task_intro here for boot-time tasks,
    201          * probably they should announce themselves explicitly
    202          * or taskman should detect them from kernel's list of tasks.
    203          */
    204         int rc = task_intro(icall, false);
    205 
    206         /* First, accept connection */
    207         async_answer_0(iid, rc);
    208 
    209         if (rc != EOK) {
    210                 return;
    211         }
    212 
    213         control_connection_loop();
    214 }
    215 
    216216static void loader_callback(ipc_callid_t iid, ipc_call_t *icall)
    217217{
     218        DPRINTF("%s:%i from %llu\n", __func__, __LINE__, icall->in_task_id);
    218219        // TODO check that loader is expected, would probably discard prodcons
    219220        //      scheme
     
    232233        }
    233234
    234         /* Remember task_id */
    235         int rc = task_intro(icall, true);
    236 
    237         if (rc != EOK) {
    238                 async_answer_0(iid, rc);
    239                 free(sess_ref);
    240                 return;
    241         }
    242235        async_answer_0(iid, EOK);
    243236
     
    247240}
    248241
     242static bool handle_call(ipc_callid_t iid, ipc_call_t *icall)
     243{
     244        switch (IPC_GET_IMETHOD(*icall)) {
     245        case TASKMAN_NEW_TASK:
     246                taskman_new_task(iid, icall);
     247                break;
     248        case TASKMAN_I_AM_NS:
     249                taskman_i_am_ns(iid, icall);
     250                break;
     251        case TASKMAN_WAIT:
     252                taskman_ctl_wait(iid, icall);
     253                break;
     254        case TASKMAN_RETVAL:
     255                taskman_ctl_retval(iid, icall);
     256                break;
     257        case TASKMAN_EVENT_CALLBACK:
     258                taskman_ctl_ev_callback(iid, icall);
     259                break;
     260        default:
     261                return false;
     262        }
     263        return true;
     264}
     265
     266static bool handle_implicit_call(ipc_callid_t iid, ipc_call_t *icall)
     267{
     268        DPRINTF("%s:%i %i(%i) from %llu\n", __func__, __LINE__,
     269            IPC_GET_IMETHOD(*icall),
     270            IPC_GET_ARG1(*icall),
     271            icall->in_task_id);
     272
     273        if (IPC_GET_IMETHOD(*icall) < IPC_FIRST_USER_METHOD) {
     274                switch (IPC_GET_ARG1(*icall)) {
     275                case TASKMAN_CONNECT_TO_NS:
     276                        connect_to_ns(iid, icall);
     277                        break;
     278                case TASKMAN_CONNECT_TO_LOADER:
     279                        connect_to_loader(iid, icall);
     280                        break;
     281                case TASKMAN_LOADER_CALLBACK:
     282                        loader_callback(iid, icall);
     283                        break;
     284                default:
     285                        return false;
     286
     287                }
     288        } else {
     289                return handle_call(iid, icall);
     290        }
     291
     292        return true;
     293}
     294
     295static void implicit_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     296{
     297        if (!handle_implicit_call(iid, icall)) {
     298                async_answer_0(iid, ENOTSUP);
     299                return;
     300        }
     301
     302        while (true) {
     303                ipc_call_t call;
     304                ipc_callid_t callid = async_get_call(&call);
     305
     306                if (!IPC_GET_IMETHOD(call)) {
     307                        /* Client disconnected */
     308                        break;
     309                }
     310
     311                if (!handle_implicit_call(callid, &call)) {
     312                        async_answer_0(callid, ENOTSUP);
     313                        break;
     314                }
     315        }
     316}
     317
    249318static void taskman_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    250319{
    251         taskman_interface_t iface = IPC_GET_ARG1(*icall);
    252         switch (iface) {
    253         case TASKMAN_CONNECT_TO_LOADER:
    254                 connect_to_loader(iid, icall);
    255                 break;
    256         case TASKMAN_LOADER_TO_NS:
    257                 loader_to_ns(iid, icall);
    258                 break;
    259         case TASKMAN_CONTROL:
    260                 control_connection(iid, icall);
    261                 break;
    262         default:
    263                 /* Unknown interface */
    264                 async_answer_0(iid, ENOENT);
    265         }
    266 }
    267 
    268 static void implicit_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    269 {
    270         taskman_interface_t iface = IPC_GET_ARG1(*icall);
    271         switch (iface) {
    272         case TASKMAN_LOADER_CALLBACK:
    273                 loader_callback(iid, icall);
    274                 control_connection_loop();
    275                 break;
    276         default:
    277                 /* Unknown interface on implicit connection */
     320        /*
     321         * We don't expect (yet) clients to connect, having this function is
     322         * just to adapt to async framework that creates new connection for
     323         * each IPC_M_CONNECT_ME_TO.
     324         * In this case those are to be forwarded, so don't continue
     325         * "listening" on such connections.
     326         */
     327        if (!handle_implicit_call(iid, icall)) {
     328                /* If cannot handle connection requst, give up trying */
    278329                async_answer_0(iid, EHANGUP);
    279         }
    280 }
     330                return;
     331        }
     332}
     333
    281334
    282335
     
    298351        rc = async_event_subscribe(EVENT_EXIT, task_exit_event, NULL);
    299352        if (rc != EOK) {
    300                 printf("Cannot register for exit events (%i).\n", rc);
     353                printf(NAME ": Cannot register for exit events (%i).\n", rc);
    301354                return rc;
    302355        }
     
    304357        rc = async_event_subscribe(EVENT_FAULT, task_fault_event, NULL);
    305358        if (rc != EOK) {
    306                 printf("Cannot register for fault events (%i).\n", rc);
     359                printf(NAME ": Cannot register for fault events (%i).\n", rc);
    307360                return rc;
    308361        }
    309 
    310         /* We're service too */
    311         rc = service_register(SERVICE_TASKMAN);
    312         if (rc != EOK) {
    313                 printf("Cannot register at naming service (%i).\n", rc);
    314                 return rc;
     362       
     363        task_id_t self_id = task_get_id();
     364        rc = task_intro(self_id);
     365        if (rc != EOK) {
     366                printf(NAME ": Cannot register self as task (%i).\n", rc);
    315367        }
    316368
    317369        /* Start sysman server */
     370        async_set_implicit_connection(implicit_connection);
    318371        async_set_client_connection(taskman_connection);
    319         async_set_implicit_connection(implicit_connection);
    320372
    321373        printf(NAME ": Accepting connections\n");
    322         //TODO task_retval(EOK);
     374        (void)task_set_retval(self_id, EOK, false);
    323375        async_manager();
    324376
  • uspace/srv/taskman/task.c

    r780c8ce r012dd8e  
    109109}
    110110
    111 int task_intro(ipc_call_t *call, bool check_unique)
     111int task_intro(task_id_t id)
    112112{
    113113        int rc = EOK;
     
    115115        fibril_rwlock_write_lock(&task_hash_table_lock);
    116116
    117         task_t *t = task_get_by_id(call->in_task_id);
     117        task_t *t = task_get_by_id(id);
    118118        if (t != NULL) {
    119119                rc = EEXISTS;
     
    130130         * Insert into the main table.
    131131         */
    132         t->id = call->in_task_id;
     132        t->id = id;
    133133        t->exit = TASK_EXIT_RUNNING;
    134134        t->failed = false;
  • uspace/srv/taskman/task.h

    r780c8ce r012dd8e  
    7070extern task_t *task_get_by_id(task_id_t);
    7171
    72 extern int task_intro(ipc_call_t *, bool);
     72extern int task_intro(task_id_t);
    7373
    7474#endif
Note: See TracChangeset for help on using the changeset viewer.