2376 // 4511530 - sem_post is serialized and handled by the manager thread. When 2377 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We 2378 // don't want to flood the manager thread with sem_post requests. 2379 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) { 2380 return; 2381 } 2382 2383 // Ctrl-C is pressed during error reporting, likely because the error 2384 // handler fails to abort. Let VM die immediately. 2385 if (sig == SIGINT && is_error_reported()) { 2386 os::die(); 2387 } 2388 2389 os::signal_notify(sig); 2390 } 2391 2392 void* os::user_handler() { 2393 return CAST_FROM_FN_PTR(void*, UserHandler); 2394 } 2395 2396 class Semaphore : public StackObj { 2397 public: 2398 Semaphore(); 2399 ~Semaphore(); 2400 void signal(); 2401 void wait(); 2402 bool trywait(); 2403 bool timedwait(unsigned int sec, int nsec); 2404 private: 2405 sem_t _semaphore; 2406 }; 2407 2408 Semaphore::Semaphore() { 2409 sem_init(&_semaphore, 0, 0); 2410 } 2411 2412 Semaphore::~Semaphore() { 2413 sem_destroy(&_semaphore); 2414 } 2415 2416 void Semaphore::signal() { 2417 sem_post(&_semaphore); 2418 } 2419 2420 void Semaphore::wait() { 2421 sem_wait(&_semaphore); 2422 } 2423 2424 bool Semaphore::trywait() { 2425 return sem_trywait(&_semaphore) == 0; 2426 } 2427 2428 bool Semaphore::timedwait(unsigned int sec, int nsec) { 2429 2430 struct timespec ts; 2431 // Semaphore's are always associated with CLOCK_REALTIME 2432 os::Linux::clock_gettime(CLOCK_REALTIME, &ts); 2433 // see unpackTime for discussion on overflow checking 2434 if (sec >= MAX_SECS) { 2435 ts.tv_sec += MAX_SECS; 2436 ts.tv_nsec = 0; 2437 } else { 2438 ts.tv_sec += sec; 2439 ts.tv_nsec += nsec; 2440 if (ts.tv_nsec >= NANOSECS_PER_SEC) { 2441 ts.tv_nsec -= NANOSECS_PER_SEC; 2442 ++ts.tv_sec; // note: this must be <= max_secs 2443 } 2444 } 2445 2446 while (1) { 2447 int result = sem_timedwait(&_semaphore, &ts); 2448 if (result == 0) { 2449 return true; 2450 } else if (errno == EINTR) { 2451 continue; 2452 } else if (errno == ETIMEDOUT) { 2453 return false; 2454 } else { 2455 return false; 2456 } 2457 } 2458 } 2459 2460 extern "C" { 2461 typedef void (*sa_handler_t)(int); 2462 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 2463 } 2464 2465 void* os::signal(int signal_number, void* handler) { 2466 struct sigaction sigAct, oldSigAct; 2467 2468 sigfillset(&(sigAct.sa_mask)); 2469 sigAct.sa_flags = SA_RESTART|SA_SIGINFO; 2470 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); 2471 2472 if (sigaction(signal_number, &sigAct, &oldSigAct)) { 2473 // -1 means registration failed 2474 return (void *)-1; 2475 } 2476 2477 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); 2478 } 2479 2480 void os::signal_raise(int signal_number) { 2481 ::raise(signal_number); 2482 } 2483 2484 // The following code is moved from os.cpp for making this 2485 // code platform specific, which it is by its very nature. 2486 2487 // Will be modified when max signal is changed to be dynamic 2488 int os::sigexitnum_pd() { 2489 return NSIG; 2490 } 2491 2492 // a counter for each possible signal value 2493 static volatile jint pending_signals[NSIG+1] = { 0 }; 2494 2495 // Linux(POSIX) specific hand shaking semaphore. 2496 static sem_t sig_sem; 2497 static Semaphore sr_semaphore; 2498 2499 void os::signal_init_pd() { 2500 // Initialize signal structures 2501 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); 2502 2503 // Initialize signal semaphore 2504 ::sem_init(&sig_sem, 0, 0); 2505 } 2506 2507 void os::signal_notify(int sig) { 2508 Atomic::inc(&pending_signals[sig]); 2509 ::sem_post(&sig_sem); 2510 } 2511 2512 static int check_pending_signals(bool wait) { 2513 Atomic::store(0, &sigint_count); 2514 for (;;) { 2515 for (int i = 0; i < NSIG + 1; i++) { 2516 jint n = pending_signals[i]; 2517 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { | 2376 // 4511530 - sem_post is serialized and handled by the manager thread. When 2377 // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We 2378 // don't want to flood the manager thread with sem_post requests. 2379 if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1) { 2380 return; 2381 } 2382 2383 // Ctrl-C is pressed during error reporting, likely because the error 2384 // handler fails to abort. Let VM die immediately. 2385 if (sig == SIGINT && is_error_reported()) { 2386 os::die(); 2387 } 2388 2389 os::signal_notify(sig); 2390 } 2391 2392 void* os::user_handler() { 2393 return CAST_FROM_FN_PTR(void*, UserHandler); 2394 } 2395 2396 class LinuxSemaphore : public os::PosixSemaphore { 2397 public: 2398 LinuxSemaphore(uint value = 0) : os::PosixSemaphore(value) {} 2399 2400 bool timedwait(unsigned int sec, int nsec) { 2401 struct timespec ts; 2402 // Semaphore's are always associated with CLOCK_REALTIME 2403 os::Linux::clock_gettime(CLOCK_REALTIME, &ts); 2404 // see unpackTime for discussion on overflow checking 2405 if (sec >= MAX_SECS) { 2406 ts.tv_sec += MAX_SECS; 2407 ts.tv_nsec = 0; 2408 } else { 2409 ts.tv_sec += sec; 2410 ts.tv_nsec += nsec; 2411 if (ts.tv_nsec >= NANOSECS_PER_SEC) { 2412 ts.tv_nsec -= NANOSECS_PER_SEC; 2413 ++ts.tv_sec; // note: this must be <= max_secs 2414 } 2415 } 2416 2417 return os::PosixSemaphore::timedwait(ts); 2418 } 2419 }; 2420 2421 extern "C" { 2422 typedef void (*sa_handler_t)(int); 2423 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 2424 } 2425 2426 void* os::signal(int signal_number, void* handler) { 2427 struct sigaction sigAct, oldSigAct; 2428 2429 sigfillset(&(sigAct.sa_mask)); 2430 sigAct.sa_flags = SA_RESTART|SA_SIGINFO; 2431 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); 2432 2433 if (sigaction(signal_number, &sigAct, &oldSigAct)) { 2434 // -1 means registration failed 2435 return (void *)-1; 2436 } 2437 2438 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); 2439 } 2440 2441 void os::signal_raise(int signal_number) { 2442 ::raise(signal_number); 2443 } 2444 2445 // The following code is moved from os.cpp for making this 2446 // code platform specific, which it is by its very nature. 2447 2448 // Will be modified when max signal is changed to be dynamic 2449 int os::sigexitnum_pd() { 2450 return NSIG; 2451 } 2452 2453 // a counter for each possible signal value 2454 static volatile jint pending_signals[NSIG+1] = { 0 }; 2455 2456 // Linux(POSIX) specific hand shaking semaphore. 2457 static sem_t sig_sem; 2458 static LinuxSemaphore sr_semaphore; 2459 2460 void os::signal_init_pd() { 2461 // Initialize signal structures 2462 ::memset((void*)pending_signals, 0, sizeof(pending_signals)); 2463 2464 // Initialize signal semaphore 2465 ::sem_init(&sig_sem, 0, 0); 2466 } 2467 2468 void os::signal_notify(int sig) { 2469 Atomic::inc(&pending_signals[sig]); 2470 ::sem_post(&sig_sem); 2471 } 2472 2473 static int check_pending_signals(bool wait) { 2474 Atomic::store(0, &sigint_count); 2475 for (;;) { 2476 for (int i = 0; i < NSIG + 1; i++) { 2477 jint n = pending_signals[i]; 2478 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { |