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

*** 988,997 **** --- 988,1048 ---- } 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. + * + * arg1 -- Linux tid + * arg2 -- signal number + * arg3 -- union sigval + */ + + proc_t *pp, *cp = curproc; + int native_sig = ltos_signo[(int)arg2]; + pid_t native_pid; + int native_tid; + sigqueue_t *sqp; + + lx_lpid_to_spair((pid_t)arg1, &native_pid, &native_tid); + + mutex_enter(&pidlock); + if (((pp = prfind(native_pid)) == NULL) || (pp->p_stat == SIDL)) { + mutex_exit(&pidlock); + return (ESRCH); + } + mutex_enter(&pp->p_lock); + mutex_exit(&pidlock); + + if ((t = idtot(pp, native_tid)) == NULL) { + mutex_exit(&pp->p_lock); + return (ESRCH); + } + + sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); + sqp->sq_info.si_signo = native_sig; + sqp->sq_info.si_code = SI_TIMER; + sqp->sq_info.si_pid = cp->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(pp, t, sqp); + + mutex_exit(&pp->p_lock); + return (0); + } + case B_SET_AFFINITY_MASK: case B_GET_AFFINITY_MASK: /* * Retrieve or store the CPU affinity mask for the * requested linux pid.