Changeset 36 for pjproject/main/pjlib/include/pj++/os.hpp
- Timestamp:
- Nov 9, 2005 3:37:19 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/main/pjlib/include/pj++/os.hpp
r29 r36 1 1 /* $Id$ 2 *3 2 */ 4 3 #ifndef __PJPP_OS_H__ … … 9 8 #include <pj++/pool.hpp> 10 9 11 class PJ_Thread 10 class Pj_Thread; 11 12 // 13 // Thread API. 14 // 15 class Pj_Thread_API 16 { 17 public: 18 // 19 // Create a thread. 20 // 21 static pj_status_t create( Pj_Pool *pool, pj_thread_t **thread, 22 pj_thread_proc *proc, void *arg, 23 unsigned flags = 0, 24 const char *name = NULL, 25 pj_size_t stack_size = 0 ) 26 { 27 return pj_thread_create(pool->pool_(), name, proc, arg, stack_size, 28 flags, thread); 29 } 30 31 // 32 // Register a thread. 33 // 34 static pj_status_t register_this_thread( pj_thread_desc desc, 35 pj_thread_t **thread, 36 const char *name = NULL ) 37 { 38 return pj_thread_register( name, desc, thread ); 39 } 40 41 // 42 // Get current thread. 43 // Will return pj_thread_t (sorry folks, not Pj_Thread). 44 // 45 static pj_thread_t *this_thread() 46 { 47 return pj_thread_this(); 48 } 49 50 // 51 // Get thread name. 52 // 53 static const char *get_name(pj_thread_t *thread) 54 { 55 return pj_thread_get_name(thread); 56 } 57 58 // 59 // Resume thread. 60 // 61 static pj_status_t resume(pj_thread_t *thread) 62 { 63 return pj_thread_resume(thread); 64 } 65 66 // 67 // Sleep. 68 // 69 static pj_status_t sleep(unsigned msec) 70 { 71 return pj_thread_sleep(msec); 72 } 73 74 // 75 // Join the specified thread. 76 // 77 static pj_status_t join(pj_thread_t *thread) 78 { 79 return pj_thread_join(thread); 80 } 81 82 // 83 // Destroy thread 84 // 85 static pj_status_t destroy(pj_thread_t *thread) 86 { 87 return pj_thread_destroy(thread); 88 } 89 }; 90 91 92 93 // 94 // Thread object. 95 // 96 // How to use: 97 // Derive a class from this class, then override main(). 98 // 99 class Pj_Thread : public Pj_Object 12 100 { 13 101 public: … … 17 105 }; 18 106 19 static PJ_Thread *create( PJ_Pool *pool, const char *thread_name, 20 pj_thread_proc *proc, void *arg, 21 pj_size_t stack_size, void *stack_ptr, 22 unsigned flags) 23 { 24 return (PJ_Thread*) pj_thread_create( pool->pool_(), thread_name, proc, arg, stack_size, stack_ptr, flags); 25 } 26 27 static PJ_Thread *register_current_thread(const char *name, pj_thread_desc desc) 28 { 29 return (PJ_Thread*) pj_thread_register(name, desc); 30 } 31 32 static PJ_Thread *get_current_thread() 33 { 34 return (PJ_Thread*) pj_thread_this(); 35 } 36 37 static pj_status_t sleep(unsigned msec) 38 { 39 return pj_thread_sleep(msec); 40 } 41 42 static pj_status_t usleep(unsigned usec) 43 { 44 return pj_thread_usleep(usec); 45 } 46 107 // 108 // Default constructor. 109 // 110 Pj_Thread() 111 : thread_(NULL) 112 { 113 } 114 115 // 116 // Destroy thread. 117 // 118 ~Pj_Thread() 119 { 120 destroy(); 121 } 122 123 // 124 // This is the main thread function. 125 // 126 virtual int main() = 0; 127 128 // 129 // Start a thread. 130 // 131 pj_status_t create( Pj_Pool *pool, 132 unsigned flags = 0, 133 const char *thread_name = NULL, 134 pj_size_t stack_size = PJ_THREAD_DEFAULT_STACK_SIZE) 135 { 136 destroy(); 137 return Pj_Thread_API::create( pool, &thread_, &thread_proc, this, 138 flags, thread_name); 139 } 140 141 // 142 // Get pjlib compatible thread object. 143 // 47 144 pj_thread_t *pj_thread_t_() 48 145 { 49 return (pj_thread_t*)this; 50 } 51 146 return thread_; 147 } 148 149 // 150 // Get thread name. 151 // 52 152 const char *get_name() 53 153 { 54 return pj_thread_get_name( this->pj_thread_t_() ); 55 } 56 154 return Pj_Thread_API::get_name(thread_); 155 } 156 157 // 158 // Resume a suspended thread. 159 // 57 160 pj_status_t resume() 58 161 { 59 return pj_thread_resume( this->pj_thread_t_() ); 60 } 61 162 return Pj_Thread_API::resume(thread_); 163 } 164 165 // 166 // Join this thread. 167 // 62 168 pj_status_t join() 63 169 { 64 return pj_thread_join( this->pj_thread_t_() ); 65 } 66 170 return Pj_Thread_API::join(thread_); 171 } 172 173 // 174 // Destroy thread. 175 // 67 176 pj_status_t destroy() 68 177 { 69 return pj_thread_destroy( this->pj_thread_t_() ); 70 } 71 }; 72 73 74 class PJ_Thread_Local 75 { 76 public: 77 static PJ_Thread_Local *alloc() 78 { 79 long index = pj_thread_local_alloc(); 80 return index < 0 ? NULL : (PJ_Thread_Local*)index; 81 } 82 void free() 83 { 84 pj_thread_local_free( this->tls_() ); 85 } 86 87 long tls_() const 88 { 89 return (long)this; 90 } 91 92 void set(void *value) 93 { 94 pj_thread_local_set( this->tls_(), value ); 95 } 96 97 void *get() 98 { 99 return pj_thread_local_get( this->tls_() ); 100 } 101 }; 102 103 104 class PJ_Atomic 105 { 106 public: 107 static PJ_Atomic *create(PJ_Pool *pool, long initial) 108 { 109 return (PJ_Atomic*) pj_atomic_create(pool->pool_(), initial); 110 } 111 178 if (thread_) { 179 Pj_Thread_API::destroy(thread_); 180 thread_ = NULL; 181 } 182 } 183 184 protected: 185 pj_thread_t *thread_; 186 187 static int PJ_THREAD_FUNC thread_proc(void *obj) 188 { 189 Pj_Thread *thread_class = (Pj_Thread*)obj; 190 return thread_class->main(); 191 } 192 }; 193 194 195 // 196 // External Thread 197 // (threads that were started by external means, i.e. not 198 // with Pj_Thread::create). 199 // 200 // This class will normally be defined as local variable in 201 // external thread's stack, normally inside thread's main proc. 202 // But be aware that the handle will be destroyed on destructor! 203 // 204 class Pj_External_Thread : public Pj_Thread 205 { 206 public: 207 Pj_External_Thread() 208 { 209 } 210 211 // 212 // Register external thread so that pjlib functions can work 213 // in that thread. 214 // 215 pj_status_t register_this_thread( const char *name=NULL ) 216 { 217 return Pj_Thread_API::register_this_thread(desc_, &thread_,name); 218 } 219 220 private: 221 pj_thread_desc desc_; 222 }; 223 224 225 // 226 // Thread specific data/thread local storage/TLS. 227 // 228 class Pj_Thread_Local_API 229 { 230 public: 231 // 232 // Allocate thread local storage (TLS) index. 233 // 234 static pj_status_t alloc(long *index) 235 { 236 return pj_thread_local_alloc(index); 237 } 238 239 // 240 // Free TLS index. 241 // 242 static void free(long index) 243 { 244 pj_thread_local_free(index); 245 } 246 247 // 248 // Set thread specific data. 249 // 250 static pj_status_t set(long index, void *value) 251 { 252 return pj_thread_local_set(index, value); 253 } 254 255 // 256 // Get thread specific data. 257 // 258 static void *get(long index) 259 { 260 return pj_thread_local_get(index); 261 } 262 263 }; 264 265 // 266 // Atomic variable 267 // 268 // How to use: 269 // Pj_Atomic_Var var(pool, 0); 270 // var.set(..); 271 // 272 class Pj_Atomic_Var : public Pj_Object 273 { 274 public: 275 // 276 // Default constructor, initialize variable with NULL. 277 // 278 Pj_Atomic_Var() 279 : var_(NULL) 280 { 281 } 282 283 // 284 // Construct atomic variable. 285 // 286 Pj_Atomic_Var(Pj_Pool *pool, pj_atomic_value_t value) 287 : var_(NULL) 288 { 289 create(pool, value); 290 } 291 292 // 293 // Destructor. 294 // 295 ~Pj_Atomic_Var() 296 { 297 destroy(); 298 } 299 300 // 301 // Create atomic variable. 302 // 303 pj_status_t create( Pj_Pool *pool, pj_atomic_value_t value) 304 { 305 destroy(); 306 return pj_atomic_create(pool->pool_(), value, &var_); 307 } 308 309 // 310 // Destroy. 311 // 312 void destroy() 313 { 314 if (var_) { 315 pj_atomic_destroy(var_); 316 var_ = NULL; 317 } 318 } 319 320 // 321 // Get pjlib compatible atomic variable. 322 // 112 323 pj_atomic_t *pj_atomic_t_() 113 324 { 114 return (pj_atomic_t*)this; 115 } 116 117 pj_status_t destroy() 118 { 119 return pj_atomic_destroy( this->pj_atomic_t_() ); 120 } 121 122 long set(long val) 123 { 124 return pj_atomic_set( this->pj_atomic_t_(), val); 125 } 126 127 long get() 128 { 129 return pj_atomic_get( this->pj_atomic_t_() ); 130 } 131 132 long inc() 133 { 134 return pj_atomic_inc( this->pj_atomic_t_() ); 135 } 136 137 long dec() 138 { 139 return pj_atomic_dec( this->pj_atomic_t_() ); 140 } 141 }; 142 143 144 class PJ_Mutex 145 { 146 public: 325 return var_; 326 } 327 328 // 329 // Set the value. 330 // 331 void set(pj_atomic_value_t val) 332 { 333 pj_atomic_set(var_, val); 334 } 335 336 // 337 // Get the value. 338 // 339 pj_atomic_value_t get() 340 { 341 return pj_atomic_get(var_); 342 } 343 344 // 345 // Increment. 346 // 347 void inc() 348 { 349 pj_atomic_inc(var_); 350 } 351 352 // 353 // Increment and get the result. 354 // 355 pj_atomic_value_t inc_and_get() 356 { 357 return pj_atomic_inc_and_get(var_); 358 } 359 360 // 361 // Decrement. 362 // 363 void dec() 364 { 365 pj_atomic_dec(var_); 366 } 367 368 // 369 // Decrement and get the result. 370 // 371 pj_atomic_value_t dec_and_get() 372 { 373 return pj_atomic_dec_and_get(var_); 374 } 375 376 // 377 // Add the variable. 378 // 379 void add(pj_atomic_value_t value) 380 { 381 pj_atomic_add(var_, value); 382 } 383 384 // 385 // Add the variable and get the value. 386 // 387 pj_atomic_value_t add_and_get(pj_atomic_value_t value) 388 { 389 return pj_atomic_add_and_get(var_, value ); 390 } 391 392 private: 393 pj_atomic_t *var_; 394 }; 395 396 397 // 398 // Mutex 399 // 400 class Pj_Mutex : public Pj_Object 401 { 402 public: 403 // 404 // Mutex type. 405 // 147 406 enum Type 148 407 { … … 152 411 }; 153 412 154 static PJ_Mutex *create( PJ_Pool *pool, const char *name, Type type) 155 { 156 return (PJ_Mutex*) pj_mutex_create( pool->pool_(), name, type); 157 } 158 159 pj_mutex_t *pj_mutex_() 160 { 161 return (pj_mutex_t*)this; 162 } 163 164 pj_status_t destroy() 165 { 166 return pj_mutex_destroy( this->pj_mutex_() ); 167 } 168 169 pj_status_t lock() 170 { 171 return pj_mutex_lock( this->pj_mutex_() ); 172 } 173 174 pj_status_t unlock() 175 { 176 return pj_mutex_unlock( this->pj_mutex_() ); 177 } 178 179 pj_status_t trylock() 180 { 181 return pj_mutex_trylock( this->pj_mutex_() ); 182 } 183 184 #if PJ_DEBUG 185 pj_status_t is_locked() 186 { 187 return pj_mutex_is_locked( this->pj_mutex_() ); 188 } 189 #endif 190 }; 191 192 193 class PJ_Semaphore 194 { 195 public: 196 static PJ_Semaphore *create( PJ_Pool *pool, const char *name, unsigned initial, unsigned max) 197 { 198 return (PJ_Semaphore*) pj_sem_create( pool->pool_(), name, initial, max); 199 } 200 413 // 414 // Default constructor will create default mutex. 415 // 416 explicit Pj_Mutex(Pj_Pool *pool, Type type = DEFAULT, 417 const char *name = NULL) 418 : mutex_(NULL) 419 { 420 create(pool, type, name); 421 } 422 423 // 424 // Destructor. 425 // 426 ~Pj_Mutex() 427 { 428 destroy(); 429 } 430 431 // 432 // Create mutex. 433 // 434 pj_status_t create( Pj_Pool *pool, Type type, const char *name = NULL) 435 { 436 destroy(); 437 return pj_mutex_create( pool->pool_(), name, type, 438 &mutex_ ); 439 } 440 441 // 442 // Create simple mutex. 443 // 444 pj_status_t create_simple( Pj_Pool *pool,const char *name = NULL) 445 { 446 return create(pool, SIMPLE, name); 447 } 448 449 // 450 // Create recursive mutex. 451 // 452 pj_status_t create_recursive( Pj_Pool *pool, const char *name = NULL ) 453 { 454 return create(pool, RECURSE, name); 455 } 456 457 // 458 // Get pjlib compatible mutex object. 459 // 460 pj_mutex_t *pj_mutex_t_() 461 { 462 return mutex_; 463 } 464 465 // 466 // Destroy mutex. 467 // 468 void destroy() 469 { 470 if (mutex_) { 471 pj_mutex_destroy(mutex_); 472 mutex_ = NULL; 473 } 474 } 475 476 // 477 // Lock mutex. 478 // 479 pj_status_t acquire() 480 { 481 return pj_mutex_lock(mutex_); 482 } 483 484 // 485 // Unlock mutex. 486 // 487 pj_status_t release() 488 { 489 return pj_mutex_unlock(mutex_); 490 } 491 492 // 493 // Try locking the mutex. 494 // 495 pj_status_t tryacquire() 496 { 497 return pj_mutex_trylock(mutex_); 498 } 499 500 private: 501 pj_mutex_t *mutex_; 502 }; 503 504 505 // 506 // Semaphore 507 // 508 class Pj_Semaphore : public Pj_Object 509 { 510 public: 511 // 512 // Construct semaphore 513 // 514 Pj_Semaphore(Pj_Pool *pool, unsigned max, 515 unsigned initial = 0, const char *name = NULL) 516 : sem_(NULL) 517 { 518 } 519 520 // 521 // Destructor. 522 // 523 ~Pj_Semaphore() 524 { 525 destroy(); 526 } 527 528 // 529 // Create semaphore 530 // 531 pj_status_t create( Pj_Pool *pool, unsigned max, 532 unsigned initial = 0, const char *name = NULL ) 533 { 534 destroy(); 535 return pj_sem_create( pool->pool_(), name, initial, max, &sem_); 536 } 537 538 // 539 // Destroy semaphore. 540 // 541 void destroy() 542 { 543 if (sem_) { 544 pj_sem_destroy(sem_); 545 sem_ = NULL; 546 } 547 } 548 549 // 550 // Get pjlib compatible semaphore object. 551 // 201 552 pj_sem_t *pj_sem_t_() 202 553 { … … 204 555 } 205 556 206 pj_status_t destroy() 207 { 208 return pj_sem_destroy(this->pj_sem_t_()); 209 } 210 557 // 558 // Wait semaphore. 559 // 211 560 pj_status_t wait() 212 561 { … … 214 563 } 215 564 216 pj_status_t lock() 565 // 566 // Wait semaphore. 567 // 568 pj_status_t acquire() 217 569 { 218 570 return wait(); 219 571 } 220 572 573 // 574 // Try wait semaphore. 575 // 221 576 pj_status_t trywait() 222 577 { … … 224 579 } 225 580 226 pj_status_t trylock() 581 // 582 // Try wait semaphore. 583 // 584 pj_status_t tryacquire() 227 585 { 228 586 return trywait(); 229 587 } 230 588 589 // 590 // Post semaphore. 591 // 231 592 pj_status_t post() 232 593 { … … 234 595 } 235 596 236 pj_status_t unlock() 597 // 598 // Post semaphore. 599 // 600 pj_status_t release() 237 601 { 238 602 return post(); 239 603 } 240 }; 241 242 243 class PJ_Event 244 { 245 public: 246 static PJ_Event *create( PJ_Pool *pool, const char *name, bool manual_reset, bool initial) 247 { 248 return (PJ_Event*) pj_event_create(pool->pool_(), name, manual_reset, initial); 249 } 250 604 605 private: 606 pj_sem_t *sem_; 607 }; 608 609 610 // 611 // Event object. 612 // 613 class Pj_Event 614 { 615 public: 616 // 617 // Construct event object. 618 // 619 Pj_Event( Pj_Pool *pool, bool manual_reset = false, 620 bool initial = false, const char *name = NULL ) 621 : event_(NULL) 622 { 623 create(pool, manual_reset, initial, name); 624 } 625 626 // 627 // Destructor. 628 // 629 ~Pj_Event() 630 { 631 destroy(); 632 } 633 634 // 635 // Create event object. 636 // 637 pj_status_t create( Pj_Pool *pool, bool manual_reset = false, 638 bool initial = false, const char *name = NULL) 639 { 640 destroy(); 641 return pj_event_create(pool->pool_(), name, manual_reset, initial, 642 &event_); 643 } 644 645 // 646 // Get pjlib compatible event object. 647 // 251 648 pj_event_t *pj_event_t_() 252 649 { 253 return (pj_event_t*)this; 254 } 255 256 pj_status_t destroy() 257 { 258 return pj_event_destroy(this->pj_event_t_()); 259 } 260 650 return event_; 651 } 652 653 // 654 // Destroy event object. 655 // 656 void destroy() 657 { 658 if (event_) { 659 pj_event_destroy(event_); 660 event_ = NULL; 661 } 662 } 663 664 // 665 // Wait. 666 // 261 667 pj_status_t wait() 262 668 { 263 return pj_event_wait(this->pj_event_t_()); 264 } 265 669 return pj_event_wait(event_); 670 } 671 672 // 673 // Try wait. 674 // 266 675 pj_status_t trywait() 267 676 { 268 return pj_event_trywait(this->pj_event_t_()); 269 } 270 677 return pj_event_trywait(event_); 678 } 679 680 // 681 // Set event state to signalled. 682 // 271 683 pj_status_t set() 272 684 { … … 274 686 } 275 687 688 // 689 // Release one waiting thread. 690 // 276 691 pj_status_t pulse() 277 692 { … … 279 694 } 280 695 696 // 697 // Set a non-signalled. 698 // 281 699 pj_status_t reset() 282 700 { 283 701 return pj_event_reset(this->pj_event_t_()); 284 702 } 285 }; 286 287 class PJ_OS 288 { 289 public: 290 static pj_status_t gettimeofday( PJ_Time_Val *tv ) 703 704 private: 705 pj_event_t *event_; 706 }; 707 708 // 709 // OS abstraction. 710 // 711 class Pj_OS_API 712 { 713 public: 714 // 715 // Get current time. 716 // 717 static pj_status_t gettimeofday( Pj_Time_Val *tv ) 291 718 { 292 719 return pj_gettimeofday(tv); 293 720 } 294 721 295 static pj_status_t time_decode( const PJ_Time_Val *tv, pj_parsed_time *pt ) 722 // 723 // Parse to time of day. 724 // 725 static pj_status_t time_decode( const Pj_Time_Val *tv, 726 pj_parsed_time *pt ) 296 727 { 297 728 return pj_time_decode(tv, pt); 298 729 } 299 730 300 static pj_status_t time_encode(const pj_parsed_time *pt, PJ_Time_Val *tv) 731 // 732 // Parse from time of day. 733 // 734 static pj_status_t time_encode( const pj_parsed_time *pt, 735 Pj_Time_Val *tv) 301 736 { 302 737 return pj_time_encode(pt, tv); 303 738 } 304 739 305 static pj_status_t time_local_to_gmt( PJ_Time_Val *tv ) 740 // 741 // Convert to GMT. 742 // 743 static pj_status_t time_local_to_gmt( Pj_Time_Val *tv ) 306 744 { 307 745 return pj_time_local_to_gmt( tv ); 308 746 } 309 747 310 static pj_status_t time_gmt_to_local( PJ_Time_Val *tv) 748 // 749 // Convert time to local. 750 // 751 static pj_status_t time_gmt_to_local( Pj_Time_Val *tv) 311 752 { 312 753 return pj_time_gmt_to_local( tv ); … … 314 755 }; 315 756 316 317 inline pj_status_t PJ_Time_Val::gettimeofday() 318 { 319 return PJ_OS::gettimeofday(this); 757 // 758 // Timeval inlines. 759 // 760 inline pj_status_t Pj_Time_Val::gettimeofday() 761 { 762 return Pj_OS_API::gettimeofday(this); 320 763 } 321 764 322 inline pj_parsed_time P J_Time_Val::decode()765 inline pj_parsed_time Pj_Time_Val::decode() 323 766 { 324 767 pj_parsed_time pt; 325 P J_OS::time_decode(this, &pt);768 Pj_OS_API::time_decode(this, &pt); 326 769 return pt; 327 770 } 328 771 329 inline pj_status_t P J_Time_Val::encode(const pj_parsed_time *pt)330 { 331 return P J_OS::time_encode(pt, this);772 inline pj_status_t Pj_Time_Val::encode(const pj_parsed_time *pt) 773 { 774 return Pj_OS_API::time_encode(pt, this); 332 775 } 333 776 334 inline pj_status_t P J_Time_Val::to_gmt()335 { 336 return P J_OS::time_local_to_gmt(this);777 inline pj_status_t Pj_Time_Val::to_gmt() 778 { 779 return Pj_OS_API::time_local_to_gmt(this); 337 780 } 338 781 339 inline pj_status_t P J_Time_Val::to_local()340 { 341 return P J_OS::time_gmt_to_local(this);782 inline pj_status_t Pj_Time_Val::to_local() 783 { 784 return Pj_OS_API::time_gmt_to_local(this); 342 785 } 343 786
Note: See TracChangeset
for help on using the changeset viewer.