2354
2355 /*
2356 * Return true if the signal number is in range
2357 * and the signal code specifies signal queueing.
2358 */
2359 int
2360 sigwillqueue(int sig, int code)
2361 {
2362 if (sig >= 0 && sig < NSIG) {
2363 switch (code) {
2364 case SI_QUEUE:
2365 case SI_TIMER:
2366 case SI_ASYNCIO:
2367 case SI_MESGQ:
2368 return (1);
2369 }
2370 }
2371 return (0);
2372 }
2373
2374 #ifndef UCHAR_MAX
2375 #define UCHAR_MAX 255
2376 #endif
2377
2378 /*
2379 * The entire pool (with maxcount entries) is pre-allocated at
2380 * the first sigqueue/signotify call.
2381 */
2382 sigqhdr_t *
2383 sigqhdralloc(size_t size, uint_t maxcount)
2384 {
2385 size_t i;
2386 sigqueue_t *sq, *next;
2387 sigqhdr_t *sqh;
2388
2389 i = (maxcount * size) + sizeof (sigqhdr_t);
2390 ASSERT(maxcount <= UCHAR_MAX && i <= USHRT_MAX);
2391 sqh = kmem_alloc(i, KM_SLEEP);
2392 sqh->sqb_count = (uchar_t)maxcount;
2393 sqh->sqb_maxcount = (uchar_t)maxcount;
2394 sqh->sqb_size = (ushort_t)i;
2395 sqh->sqb_pexited = 0;
2396 sqh->sqb_sent = 0;
2397 sqh->sqb_free = sq = (sigqueue_t *)(sqh + 1);
2398 for (i = maxcount - 1; i != 0; i--) {
2399 next = (sigqueue_t *)((uintptr_t)sq + size);
2400 sq->sq_next = next;
2401 sq = next;
2402 }
2403 sq->sq_next = NULL;
2404 cv_init(&sqh->sqb_cv, NULL, CV_DEFAULT, NULL);
2405 mutex_init(&sqh->sqb_lock, NULL, MUTEX_DEFAULT, NULL);
2406 return (sqh);
2407 }
2408
2409 static void sigqrel(sigqueue_t *);
2410
2411 /*
2412 * allocate a sigqueue/signotify structure from the per process
2413 * pre-allocated pool.
2414 */
2415 sigqueue_t *
2416 sigqalloc(sigqhdr_t *sqh)
2417 {
2418 sigqueue_t *sq = NULL;
2419
2420 ASSERT(MUTEX_HELD(&curproc->p_lock));
2421
2422 if (sqh != NULL) {
2423 mutex_enter(&sqh->sqb_lock);
2424 if (sqh->sqb_count > 0) {
2425 sqh->sqb_count--;
2426 sq = sqh->sqb_free;
2427 sqh->sqb_free = sq->sq_next;
2428 mutex_exit(&sqh->sqb_lock);
2429 bzero(&sq->sq_info, sizeof (k_siginfo_t));
2430 sq->sq_backptr = sqh;
2431 sq->sq_func = sigqrel;
2432 sq->sq_next = NULL;
2433 sq->sq_external = 0;
2434 } else {
2435 mutex_exit(&sqh->sqb_lock);
2436 }
2437 }
2438 return (sq);
2439 }
2440
2441 /*
2442 * Return a sigqueue structure back to the pre-allocated pool.
2443 */
2444 static void
2445 sigqrel(sigqueue_t *sq)
2446 {
2447 sigqhdr_t *sqh;
2448
2449 /* make sure that p_lock of the affected process is held */
2450
2451 sqh = (sigqhdr_t *)sq->sq_backptr;
|
2354
2355 /*
2356 * Return true if the signal number is in range
2357 * and the signal code specifies signal queueing.
2358 */
2359 int
2360 sigwillqueue(int sig, int code)
2361 {
2362 if (sig >= 0 && sig < NSIG) {
2363 switch (code) {
2364 case SI_QUEUE:
2365 case SI_TIMER:
2366 case SI_ASYNCIO:
2367 case SI_MESGQ:
2368 return (1);
2369 }
2370 }
2371 return (0);
2372 }
2373
2374 /*
2375 * The pre-allocated pool (with _SIGQUEUE_PREALLOC entries) is
2376 * allocated at the first sigqueue/signotify call.
2377 */
2378 sigqhdr_t *
2379 sigqhdralloc(size_t size, uint_t maxcount)
2380 {
2381 size_t i;
2382 sigqueue_t *sq, *next;
2383 sigqhdr_t *sqh;
2384
2385 /*
2386 * Before the introduction of process.max-sigqueue-size
2387 * _SC_SIGQUEUE_MAX had this static value.
2388 */
2389 #define _SIGQUEUE_PREALLOC 32
2390
2391 i = (_SIGQUEUE_PREALLOC * size) + sizeof (sigqhdr_t);
2392 ASSERT(maxcount <= INT_MAX);
2393 sqh = kmem_alloc(i, KM_SLEEP);
2394 sqh->sqb_count = maxcount;
2395 sqh->sqb_maxcount = maxcount;
2396 sqh->sqb_size = i;
2397 sqh->sqb_pexited = 0;
2398 sqh->sqb_sent = 0;
2399 sqh->sqb_free = sq = (sigqueue_t *)(sqh + 1);
2400 for (i = _SIGQUEUE_PREALLOC - 1; i != 0; i--) {
2401 next = (sigqueue_t *)((uintptr_t)sq + size);
2402 sq->sq_next = next;
2403 sq = next;
2404 }
2405 sq->sq_next = NULL;
2406 cv_init(&sqh->sqb_cv, NULL, CV_DEFAULT, NULL);
2407 mutex_init(&sqh->sqb_lock, NULL, MUTEX_DEFAULT, NULL);
2408 return (sqh);
2409 }
2410
2411 static void sigqrel(sigqueue_t *);
2412
2413 /*
2414 * Allocate a sigqueue/signotify structure from the per process
2415 * pre-allocated pool or allocate a new sigqueue/signotify structure
2416 * if the pre-allocated pool is exhausted.
2417 */
2418 sigqueue_t *
2419 sigqalloc(sigqhdr_t *sqh)
2420 {
2421 sigqueue_t *sq = NULL;
2422
2423 ASSERT(MUTEX_HELD(&curproc->p_lock));
2424
2425 if (sqh != NULL) {
2426 mutex_enter(&sqh->sqb_lock);
2427 if (sqh->sqb_count > 0) {
2428 sqh->sqb_count--;
2429 if (sqh->sqb_free == NULL) {
2430 /*
2431 * The pre-allocated pool is exhausted.
2432 */
2433 sq = kmem_alloc(sizeof (sigqueue_t), KM_SLEEP);
2434 sq->sq_func = NULL;
2435 } else {
2436 sq = sqh->sqb_free;
2437 sq->sq_func = sigqrel;
2438 sqh->sqb_free = sq->sq_next;
2439 }
2440 mutex_exit(&sqh->sqb_lock);
2441 bzero(&sq->sq_info, sizeof (k_siginfo_t));
2442 sq->sq_backptr = sqh;
2443 sq->sq_next = NULL;
2444 sq->sq_external = 0;
2445 } else {
2446 mutex_exit(&sqh->sqb_lock);
2447 }
2448 }
2449 return (sq);
2450 }
2451
2452 /*
2453 * Return a sigqueue structure back to the pre-allocated pool.
2454 */
2455 static void
2456 sigqrel(sigqueue_t *sq)
2457 {
2458 sigqhdr_t *sqh;
2459
2460 /* make sure that p_lock of the affected process is held */
2461
2462 sqh = (sigqhdr_t *)sq->sq_backptr;
|