Print this page
3830 SIGQUEUE_MAX's limit of 32 is too low


2356 
2357 /*
2358  * Return true if the signal number is in range
2359  * and the signal code specifies signal queueing.
2360  */
2361 int
2362 sigwillqueue(int sig, int code)
2363 {
2364         if (sig >= 0 && sig < NSIG) {
2365                 switch (code) {
2366                 case SI_QUEUE:
2367                 case SI_TIMER:
2368                 case SI_ASYNCIO:
2369                 case SI_MESGQ:
2370                         return (1);
2371                 }
2372         }
2373         return (0);
2374 }
2375 
2376 #ifndef UCHAR_MAX
2377 #define UCHAR_MAX       255
2378 #endif
2379 
2380 /*
2381  * The entire pool (with maxcount entries) is pre-allocated at
2382  * the first sigqueue/signotify call.
2383  */
2384 sigqhdr_t *
2385 sigqhdralloc(size_t size, uint_t maxcount)
2386 {
2387         size_t i;
2388         sigqueue_t *sq, *next;
2389         sigqhdr_t *sqh;
2390 
2391         i = (maxcount * size) + sizeof (sigqhdr_t);
2392         ASSERT(maxcount <= UCHAR_MAX && i <= USHRT_MAX);






2393         sqh = kmem_alloc(i, KM_SLEEP);
2394         sqh->sqb_count = (uchar_t)maxcount;
2395         sqh->sqb_maxcount = (uchar_t)maxcount;
2396         sqh->sqb_size = (ushort_t)i;
2397         sqh->sqb_pexited = 0;
2398         sqh->sqb_sent = 0;
2399         sqh->sqb_free = sq = (sigqueue_t *)(sqh + 1);
2400         for (i = maxcount - 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.

2416  */
2417 sigqueue_t *
2418 sigqalloc(sigqhdr_t *sqh)
2419 {
2420         sigqueue_t *sq = NULL;
2421 
2422         ASSERT(MUTEX_HELD(&curproc->p_lock));
2423 
2424         if (sqh != NULL) {
2425                 mutex_enter(&sqh->sqb_lock);
2426                 if (sqh->sqb_count > 0) {
2427                         sqh->sqb_count--;







2428                         sq = sqh->sqb_free;

2429                         sqh->sqb_free = sq->sq_next;

2430                         mutex_exit(&sqh->sqb_lock);
2431                         bzero(&sq->sq_info, sizeof (k_siginfo_t));
2432                         sq->sq_backptr = sqh;
2433                         sq->sq_func = sigqrel;
2434                         sq->sq_next = NULL;
2435                         sq->sq_external = 0;
2436                 } else {
2437                         mutex_exit(&sqh->sqb_lock);
2438                 }
2439         }
2440         return (sq);
2441 }
2442 
2443 /*
2444  * Return a sigqueue structure back to the pre-allocated pool.
2445  */
2446 static void
2447 sigqrel(sigqueue_t *sq)
2448 {
2449         sigqhdr_t *sqh;
2450 
2451         /* make sure that p_lock of the affected process is held */
2452 
2453         sqh = (sigqhdr_t *)sq->sq_backptr;




2356 
2357 /*
2358  * Return true if the signal number is in range
2359  * and the signal code specifies signal queueing.
2360  */
2361 int
2362 sigwillqueue(int sig, int code)
2363 {
2364         if (sig >= 0 && sig < NSIG) {
2365                 switch (code) {
2366                 case SI_QUEUE:
2367                 case SI_TIMER:
2368                 case SI_ASYNCIO:
2369                 case SI_MESGQ:
2370                         return (1);
2371                 }
2372         }
2373         return (0);
2374 }
2375 




2376 /*
2377  * The pre-allocated pool (with _SIGQUEUE_PREALLOC entries) is
2378  * allocated at the first sigqueue/signotify call.
2379  */
2380 sigqhdr_t *
2381 sigqhdralloc(size_t size, uint_t maxcount)
2382 {
2383         size_t i;
2384         sigqueue_t *sq, *next;
2385         sigqhdr_t *sqh;
2386 
2387         /*
2388          * Before the introduction of process.max-sigqueue-size
2389          * _SC_SIGQUEUE_MAX had this static value.
2390          */
2391 #define _SIGQUEUE_PREALLOC      32
2392 
2393         i = (_SIGQUEUE_PREALLOC * size) + sizeof (sigqhdr_t);
2394         ASSERT(maxcount <= INT_MAX);
2395         sqh = kmem_alloc(i, KM_SLEEP);
2396         sqh->sqb_count = maxcount;
2397         sqh->sqb_maxcount = maxcount;
2398         sqh->sqb_size = i;
2399         sqh->sqb_pexited = 0;
2400         sqh->sqb_sent = 0;
2401         sqh->sqb_free = sq = (sigqueue_t *)(sqh + 1);
2402         for (i = _SIGQUEUE_PREALLOC - 1; i != 0; i--) {
2403                 next = (sigqueue_t *)((uintptr_t)sq + size);
2404                 sq->sq_next = next;
2405                 sq = next;
2406         }
2407         sq->sq_next = NULL;
2408         cv_init(&sqh->sqb_cv, NULL, CV_DEFAULT, NULL);
2409         mutex_init(&sqh->sqb_lock, NULL, MUTEX_DEFAULT, NULL);
2410         return (sqh);
2411 }
2412 
2413 static void sigqrel(sigqueue_t *);
2414 
2415 /*
2416  * Allocate a sigqueue/signotify structure from the per process
2417  * pre-allocated pool or allocate a new sigqueue/signotify structure
2418  * if the pre-allocated pool is exhausted.
2419  */
2420 sigqueue_t *
2421 sigqalloc(sigqhdr_t *sqh)
2422 {
2423         sigqueue_t *sq = NULL;
2424 
2425         ASSERT(MUTEX_HELD(&curproc->p_lock));
2426 
2427         if (sqh != NULL) {
2428                 mutex_enter(&sqh->sqb_lock);
2429                 if (sqh->sqb_count > 0) {
2430                         sqh->sqb_count--;
2431                         if (sqh->sqb_free == NULL) {
2432                                 /*
2433                                  * The pre-allocated pool is exhausted.
2434                                  */
2435                                 sq = kmem_alloc(sizeof (sigqueue_t), KM_SLEEP);
2436                                 sq->sq_func = NULL;
2437                         } else {
2438                                 sq = sqh->sqb_free;
2439                                 sq->sq_func = sigqrel;
2440                                 sqh->sqb_free = sq->sq_next;
2441                         }
2442                         mutex_exit(&sqh->sqb_lock);
2443                         bzero(&sq->sq_info, sizeof (k_siginfo_t));
2444                         sq->sq_backptr = sqh;

2445                         sq->sq_next = NULL;
2446                         sq->sq_external = 0;
2447                 } else {
2448                         mutex_exit(&sqh->sqb_lock);
2449                 }
2450         }
2451         return (sq);
2452 }
2453 
2454 /*
2455  * Return a sigqueue structure back to the pre-allocated pool.
2456  */
2457 static void
2458 sigqrel(sigqueue_t *sq)
2459 {
2460         sigqhdr_t *sqh;
2461 
2462         /* make sure that p_lock of the affected process is held */
2463 
2464         sqh = (sigqhdr_t *)sq->sq_backptr;