Fix sigevent's POSIX incompatible problem by adding member fields

sigev_notify_function and sigev_notify_attributes. AIO syscalls
use sigevent, so they have to be adjusted.

Reviewed by:	alc
This commit is contained in:
David Xu 2005-10-30 02:12:49 +00:00
parent 70293cc76a
commit 0972628aff
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=151867
5 changed files with 104 additions and 35 deletions

View File

@ -467,9 +467,11 @@
u_int nfds, int timeout); }
253 AUE_NULL MSTD { int issetugid(void); }
254 AUE_NULL MSTD { int lchown(char *path, int uid, int gid); }
255 AUE_NULL UNIMPL nosys
256 AUE_NULL UNIMPL nosys
257 AUE_NULL UNIMPL nosys
255 AUE_NULL NOSTD { int aio_read(struct aiocb *aiocbp); }
256 AUE_NULL NOSTD { int aio_write(struct aiocb *aiocbp); }
257 AUE_NULL NOSTD { int lio_listio(int mode, \
struct aiocb * const *acb_list, \
int nent, struct sigevent *sig); }
258 AUE_NULL UNIMPL nosys
259 AUE_NULL UNIMPL nosys
260 AUE_NULL UNIMPL nosys
@ -551,11 +553,11 @@
316 AUE_NULL NOSTD { int aio_cancel(int fd, \
struct aiocb *aiocbp); }
317 AUE_NULL NOSTD { int aio_error(struct aiocb *aiocbp); }
318 AUE_NULL NOSTD { int aio_read(struct aiocb *aiocbp); }
319 AUE_NULL NOSTD { int aio_write(struct aiocb *aiocbp); }
320 AUE_NULL NOSTD { int lio_listio(int mode, \
struct aiocb * const *acb_list, \
int nent, struct sigevent *sig); }
318 AUE_NULL NOSTD { int oaio_read(struct oaiocb *aiocbp); }
319 AUE_NULL NOSTD { int oaio_write(struct oaiocb *aiocbp); }
320 AUE_NULL NOSTD { int olio_listio(int mode, \
struct oaiocb * const *acb_list, \
int nent, struct osigevent *sig); }
321 AUE_NULL MSTD { int yield(void); }
322 AUE_NULL OBSOL thr_sleep
323 AUE_NULL OBSOL thr_wakeup

View File

@ -170,6 +170,17 @@ static int max_buf_aio = MAX_BUF_AIO;
SYSCTL_INT(_vfs_aio, OID_AUTO, max_buf_aio, CTLFLAG_RW, &max_buf_aio, 0,
"Maximum buf aio requests per process (stored in the process)");
typedef struct oaiocb {
int aio_fildes; /* File descriptor */
off_t aio_offset; /* File offset for I/O */
volatile void *aio_buf; /* I/O buffer in process space */
size_t aio_nbytes; /* Number of bytes for I/O */
struct osigevent aio_sigevent; /* Signal to deliver */
int aio_lio_opcode; /* LIO opcode */
int aio_reqprio; /* Request priority -- ignored */
struct __aiocb_private _aiocb_private;
} oaiocb_t;
struct aiocblist {
TAILQ_ENTRY(aiocblist) list; /* List of jobs */
TAILQ_ENTRY(aiocblist) plist; /* List of jobs for proc */
@ -254,7 +265,8 @@ static void aio_onceonly(void);
static int aio_free_entry(struct aiocblist *aiocbe);
static void aio_process(struct aiocblist *aiocbe);
static int aio_newproc(void);
static int aio_aqueue(struct thread *td, struct aiocb *job, int type);
static int aio_aqueue(struct thread *td, struct aiocb *job, int type,
int osigev);
static void aio_physwakeup(struct buf *bp);
static void aio_proc_rundown(void *arg, struct proc *p);
static int aio_fphysio(struct aiocblist *aiocbe);
@ -271,6 +283,8 @@ static int filt_lio(struct knote *kn, long hint);
#define DONE_BUF 1
#define DONE_QUEUE 2
static void aio_bio_done_notify( struct proc *userp, struct aiocblist *aiocbe, int type);
static int do_lio_listio(struct thread *td, struct lio_listio_args *uap,
int oldsigev);
/*
* Zones for:
@ -328,6 +342,9 @@ SYSCALL_MODULE_HELPER(aio_read);
SYSCALL_MODULE_HELPER(aio_write);
SYSCALL_MODULE_HELPER(aio_waitcomplete);
SYSCALL_MODULE_HELPER(lio_listio);
SYSCALL_MODULE_HELPER(oaio_read);
SYSCALL_MODULE_HELPER(oaio_write);
SYSCALL_MODULE_HELPER(olio_listio);
DECLARE_MODULE(aio, aio_mod,
SI_SUB_VFS, SI_ORDER_ANY);
@ -1320,7 +1337,8 @@ aio_swake_cb(struct socket *so, struct sockbuf *sb)
* technique is done in this code.
*/
static int
_aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int type)
_aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj,
int type, int oldsigev)
{
struct proc *p = td->td_proc;
struct filedesc *fdp;
@ -1348,7 +1366,14 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
suword(&job->_aiocb_private.error, 0);
suword(&job->_aiocb_private.kernelinfo, -1);
error = copyin(job, &aiocbe->uaiocb, sizeof(aiocbe->uaiocb));
if (oldsigev) {
bzero(&aiocbe->uaiocb, sizeof(struct aiocb));
error = copyin(job, &aiocbe->uaiocb, sizeof(struct oaiocb));
bcopy(&aiocbe->uaiocb.__spare__, &aiocbe->uaiocb.aio_sigevent,
sizeof(struct osigevent));
} else {
error = copyin(job, &aiocbe->uaiocb, sizeof(struct aiocb));
}
if (error) {
suword(&job->_aiocb_private.error, error);
uma_zfree(aiocb_zone, aiocbe);
@ -1558,7 +1583,7 @@ _aio_aqueue(struct thread *td, struct aiocb *job, struct aio_liojob *lj, int typ
* This routine queues an AIO request, checking for quotas.
*/
static int
aio_aqueue(struct thread *td, struct aiocb *job, int type)
aio_aqueue(struct thread *td, struct aiocb *job, int type, int oldsigev)
{
struct proc *p = td->td_proc;
struct kaioinfo *ki;
@ -1573,7 +1598,7 @@ aio_aqueue(struct thread *td, struct aiocb *job, int type)
if (ki->kaio_queue_count >= ki->kaio_qallowed_count)
return (EAGAIN);
return _aio_aqueue(td, job, NULL, type);
return _aio_aqueue(td, job, NULL, type, oldsigev);
}
/*
@ -1956,24 +1981,51 @@ aio_error(struct thread *td, struct aio_error_args *uap)
}
/* syscall - asynchronous read from a file (REALTIME) */
int
oaio_read(struct thread *td, struct oaio_read_args *uap)
{
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, LIO_READ, 1);
}
int
aio_read(struct thread *td, struct aio_read_args *uap)
{
return aio_aqueue(td, uap->aiocbp, LIO_READ);
return aio_aqueue(td, uap->aiocbp, LIO_READ, 0);
}
/* syscall - asynchronous write to a file (REALTIME) */
int
oaio_write(struct thread *td, struct oaio_write_args *uap)
{
return aio_aqueue(td, (struct aiocb *)uap->aiocbp, LIO_WRITE, 1);
}
int
aio_write(struct thread *td, struct aio_write_args *uap)
{
return aio_aqueue(td, uap->aiocbp, LIO_WRITE);
return aio_aqueue(td, uap->aiocbp, LIO_WRITE, 0);
}
/* syscall - list directed I/O (REALTIME) */
int
olio_listio(struct thread *td, struct olio_listio_args *uap)
{
return do_lio_listio(td, (struct lio_listio_args *)uap, 1);
}
/* syscall - list directed I/O (REALTIME) */
int
lio_listio(struct thread *td, struct lio_listio_args *uap)
{
return do_lio_listio(td, uap, 0);
}
static int
do_lio_listio(struct thread *td, struct lio_listio_args *uap, int oldsigev)
{
struct proc *p = td->td_proc;
int nent, nentqueued;
@ -2023,8 +2075,10 @@ lio_listio(struct thread *td, struct lio_listio_args *uap)
* Setup signal.
*/
if (uap->sig && (uap->mode == LIO_NOWAIT)) {
bzero(&lj->lioj_signal, sizeof(&lj->lioj_signal));
error = copyin(uap->sig, &lj->lioj_signal,
sizeof(lj->lioj_signal));
oldsigev ? sizeof(struct osigevent) :
sizeof(struct sigevent));
if (error) {
uma_zfree(aiolio_zone, lj);
return (error);
@ -2071,7 +2125,7 @@ lio_listio(struct thread *td, struct lio_listio_args *uap)
for (i = 0; i < uap->nent; i++) {
iocb = (struct aiocb *)(intptr_t)fuword(&cbptr[i]);
if (((intptr_t)iocb != -1) && ((intptr_t)iocb != 0)) {
error = _aio_aqueue(td, iocb, lj, 0);
error = _aio_aqueue(td, iocb, lj, 0, oldsigev);
if (error == 0)
nentqueued++;
else

View File

@ -66,10 +66,11 @@ typedef struct aiocb {
off_t aio_offset; /* File offset for I/O */
volatile void *aio_buf; /* I/O buffer in process space */
size_t aio_nbytes; /* Number of bytes for I/O */
struct sigevent aio_sigevent; /* Signal to deliver */
char __spare__[sizeof(int) * 2 + sizeof(void *)]; /* osigevent. */
int aio_lio_opcode; /* LIO opcode */
int aio_reqprio; /* Request priority -- ignored */
struct __aiocb_private _aiocb_private;
struct sigevent aio_sigevent; /* Signal to deliver */
} aiocb_t;
#ifndef _KERNEL

View File

@ -158,28 +158,31 @@ union sigval {
#if __POSIX_VISIBLE >= 199309
struct sigevent {
int sigev_notify; /* Notification type */
union {
int __sigev_signo; /* Signal number */
int __sigev_notify_kqueue;
} __sigev_u;
int sigev_signo; /* Signal number */
union sigval sigev_value; /* Signal value */
/*
* XXX missing sigev_notify_function, sigev_notify_attributes.
*/
union {
__lwpid_t _threadid;
struct {
void (*_function)(union sigval *);
void *_attribute; /* pthread_attr_t * */
} _sigev_thread;
} _sigev_un;
};
#define sigev_signo __sigev_u.__sigev_signo
#if __BSD_VISIBLE
#define sigev_notify_kqueue __sigev_u.__sigev_notify_kqueue
#endif
#define SIGEV_NONE 0 /* No async notification */
#define SIGEV_SIGNAL 1 /* Generate a queued signal */
#if __BSD_VISIBLE
#define SIGEV_KEVENT 3 /* Generate a kevent */
#define sigev_notify_kqueue sigev_signo
#define sigev_notify_thread_id _sigev_un._threadid
#endif
#define sigev_notify_function _sigev_un._sigev_thread._function
#define sigev_notify_attributes _sigev_un._sigev_thread._attribute
#define SIGEV_NONE 0 /* No async notification. */
#define SIGEV_SIGNAL 1 /* Generate a queued signal. */
#define SIGEV_THREAD 2 /* Call back from another pthread. */
#if __BSD_VISIBLE
#define SIGEV_KEVENT 3 /* Generate a kevent. */
#define SIGEV_THREAD_ID 4 /* Send signal to a kernel thread. */
#endif
/*
* XXX missing SIGEV_THREAD.
*/
#endif /* __POSIX_VISIBLE >= 199309 */
#if __POSIX_VISIBLE >= 199309 || __XSI_VISIBLE

View File

@ -199,6 +199,15 @@ __sigseteq(sigset_t *set1, sigset_t *set2)
return (1);
}
struct osigevent {
int sigev_notify; /* Notification type */
union {
int __sigev_signo; /* Signal number */
int __sigev_notify_kqueue;
} __sigev_u;
union sigval sigev_value; /* Signal value */
};
typedef struct ksiginfo {
TAILQ_ENTRY(ksiginfo) ksi_link;
siginfo_t ksi_info;