First question, did you develop this "ad framework" for wordpress or are you using a third party plugin? The reason I ask, is the way they are doing deletes is horrid. There are a lot of ways this can be improved upon but I'll need a bit more information.
First off, what does a2p_is_expired_post do? I'm assuming it is looking at meta data and determining if the end date is before today's date (thus the ad isn't being shown anymore), is that correct? Regardless can you indicate which table that data is stored in and how it relates to the posts table?
A quick fix to this would be only returning posts you KNOW to be expired, that will greatly reduce the number of posts you loop through (and their attachments). Can you give us an idea how often ads expire and how many are usually deleted when this process is run? Are we talking 50 ads, 250, 1000?
Depending on how many you need to be able to delete per run, a quick fix might not be the solution, and you may need to refine the innards of your foreach loops too (but we can tackle that after we solve the initial problem of returning what seems to be TOO much data to be processed)