Print this page
OS-???? [lx] SIGEV_THREAD_ID emulation needed

*** 988,997 **** --- 988,1050 ---- } return (0); } + case B_SIGEV_THREAD_ID: { + /* + * Emulate Linux's timer_create(2) SIGEV_THREAD_ID + * notification method. This mechanism is only meant + * for userland threading libraries such as glibc and + * is documented as such. Therefore, assume this is + * only ever invoked for the purpose of alerting a + * Linux threading library. Assume that the tid is a + * member of the caller's process and the signal + * number is valid. See lx_sigev_thread_id() for the + * userland side of this emulation. + * + * The return code from this function is not checked + * by the caller since it executes in an asynchronous + * context and there is nothing much to be done. If + * this function does fail then it will manifest as + * Linux threads waiting for a signal they will never + * receive. + * + * arg1 -- Linux tid + * arg2 -- signal number + * arg3 -- union sigval + */ + + int native_sig = lx_stol_signo((int)arg2, LX_SIGTIMER); + pid_t native_pid; + int native_tid; + sigqueue_t *sqp; + + lx_lpid_to_spair((pid_t)arg1, &native_pid, &native_tid); + sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); + mutex_enter(&curproc->p_lock); + + if ((t = idtot(curproc, native_tid)) == NULL) { + mutex_exit(&curproc->p_lock); + kmem_free(sqp, sizeof (sigqueue_t)); + return (ESRCH); + } + + sqp->sq_info.si_signo = native_sig; + sqp->sq_info.si_code = SI_TIMER; + sqp->sq_info.si_pid = curproc->p_pid; + sqp->sq_info.si_zoneid = getzoneid(); + sqp->sq_info.si_uid = crgetruid(CRED()); + sqp->sq_info.si_value = (union sigval)((void *)arg3); + sigaddqa(curproc, t, sqp); + + mutex_exit(&curproc->p_lock); + kmem_free(sqp, sizeof (sigqueue_t)); + + return (0); + } + case B_SET_AFFINITY_MASK: case B_GET_AFFINITY_MASK: /* * Retrieve or store the CPU affinity mask for the * requested linux pid.