Using UDRIE0 interrupt in ATmega168
Interrupts are managed by hardware and fired immediately when any type of event occurs, e.g. when data register is empty, transmission of data is complete, etc.

If you implement ISR sub-routine for given type of interrupt an actual executing application code is interrupted immediatelly when the interrupt is fired and this sub-routine is executed, I.e. a long jump in program memory. Before execution of the sub-routine all relevant registers are pushed to a stack and restored when the sub-routine is finished. After serving the interrupt the interrupted application code continues from the address where it was interrupted.

A code of sub-routines must be as small as possible and must be executed quickly, so there should not be any delays or long loops. If you want to process received UART data you should put them to a buffer in the sub-routine and process in the main loop.

In case of atmel microcontrollers the interrupt flags, e.g. UDRE, are automatically cleared when the sub-routines is finished. No need to clear them by software.

Hope my explanation of interrupts is clear and will help you to write correct code.