Implement a thread-safe bounded priority queue for tasks. The queue stores tasks as (priority, task_id, payload) and supports concurrent producers and consumers. Write a class with methods push(priority, task_id, payload), pop(), and size(). If the queue is full, push must block until space is available; if it is empty, pop must block until an item is available. Higher priority values must be returned first, and tasks with the same priority must be returned in FIFO insertion order.
1 <= capacity <= 10^510^5 total push and pop operations in a testpriority is an integer in the range [-10^9, 10^9]task_id values are unique per successful push