<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def put(self, tpart):
 """Upload a tar volume Blocks if there is too much work outstanding already, and raise errors of previously submitted greenlets that die unexpectedly. """

        if self.closed:
            raise UserCritical(msg='attempt to upload tar after closing',
                               hint='report a bug')

        while True:
            too_many = (
                self.concurrency_burden + 1 > self.max_concurrency
                or self.member_burden + len(tpart) > self.max_members
            )

            if too_many:
                # If there are not enough resources to start an upload
                # even with zero uploads in progress, then something
                # has gone wrong: the user should not be given enough
                # rope to hang themselves in this way.
                if self.concurrency_burden == 0:
                    raise UserCritical(
                        msg=('not enough resources in pool to '
                             'support an upload'),
                        hint='report a bug')

                # _wait blocks until an upload finishes and clears its
                # used resources, after which another attempt to
                # evaluate scheduling resources for another upload
                # might be worth evaluating.
                #
                # Alternatively, an error was encountered in a
                # previous upload in which case it'll be raised here
                # and cause the process to regard the upload as a
                # failure.
                self._wait()
                gc.collect()
            else:
                # Enough resources available: commence upload
                self._start(tpart)
                return