The basic steps necessary to enqueue one or more messages to the MTA are:
Initialize SDK resources and data structures with mtaInit().
For each message to enqueue:
Specify the message envelope with mtaEnqueueStart() and mtaEnqueueTo().
Specify the message header with mtaEnqueueWrite() or mtaEnqueueWriteLine().
Optionally, if a message body is to be supplied, terminate the message header and start the message body by writing a blank line to the message with mtaEnqueueWrite() or mtaEnqueueWriteLine().
Optionally if a message body is to be supplied, write the message body with mtaEnqueueWrite() or mtaEnqueueWriteLine().
Submit the message with mtaEnqueueFinish().
When you have completed enqueuing messages, deallocate SDK resources and data structures with mtaDone().
In Step 2e, mtaEnqueueFinish() commits the message to disk. As part of the enqueue process, the MTA performs any access checks, size checks, format conversions, address rewritings, and other tasks called for by the site’s MTA configuration. After these steps are completed and the message has been successfully written to disk, mtaEnqueueFinish() returns.
Other MTA processes controlled by the MTA Job Controller then begin processing the new message so as to effect its delivery. In fact, these processes may begin handling the new message before mtaEnqueueFinish() even returns. As such, mtaEnqeueueFinish() doesn’t block waiting on these processes; it returns as soon as all requisite copies of the enqueued message have been safely written to disk. The subsequent handling of the newly enqueued message is performed by other MTA processes, and the program which enqueued the message isn’t left waiting for them.
A message submission can be aborted at any point in Step 2 by calling either mtaEnqueueFinish() with the MTA_ABORT option specified or mtaDone(). Using the first method, mtaEnqueueFinish() aborts only the specified message enqueue context while allowing additional messages to be enqueued. Whereas, mtaDone() aborts all active message enqueue contexts in all threads, and deallocates SDK resources disallowing any further submission attempts until the SDK is again initialized.