=begin pod

=head1 NAME

LibCurl::MultiHandle

=head1 SYNOPSIS

  use LibCurl::EasyHandle;
  use LibCurl::MultiHandle;

  curl_global_init(CURL_GLOBAL_DEFAULT);

  my $easy = LibCurl::EasyHandle.new;
  $easy.setopt(CURLOPT_URL, "http://example.com");

  my $multi = LibCurl::MultiHandle.new;

  $multi.setopt(CURLMOPT_MAXCONNECT, 1);

  $multi.add-handle($easy);

  my int32 $running-handles = 1;
  my int32 $numfds = 0;
  my $timeout-ms = 1000;
  
  repeat
  {
      $multi.perform($running-handles);
      $multi.wait($timeout-ms, $numfds);
      my int32 $msgs-in-queue = 0;
      while my $msg = $!multi.info($msgs-in-queue)
      {
          next unless $msg.msg == CURLMSG_DONE;
	  my $easy = $msg.handle;
	  $multi.remove-handle($easy);
	  $easy.cleanup;
      }
  } while $running-handles;

  $multi.cleanup;

  curl_global_cleanup;

=head1 DESCRIPTION

C<LibCurl::MultiHandle> is the low level NativeCall interface to
libcurl's L<multi
interface|https://curl.haxx.se/libcurl/c/libcurl-multi.html>. In
general you should be using the C<LibCurl::Multi> interface instead.

=head1 CLASSES

=head2 class B<LibCurl::CURLMsg> is repr('CStruct')

Wrapper for B<struct CURLMsg>

=item has uint32 $.msg

=item has LibCurl::EasyHandle $.handle

=item has uint32 $.code

=head2 class B<X::LibCurl::Multi> is X::LibCurl

Exception, just like L<X::LibCurl>, but for B<CURLMcode>.

=item method B<message>() returns Str

Returns the Str version of the errror with
L<B<curl_multi_strerror>|https://curl.haxx.se/libcurl/c/curl_multi_strerror.html>.

=head3 class B<LibCurl::MultiHandle> is repr('CPointer')

Wrapper for pointer to a B<struct CURLM>.

=item method B<new>() returns LibCurl::MultiHandle

Wrapper for
L<B<curl_multi_init>|https://curl.haxx.se/libcurl/c/curl_multi_init.html>.

=item method B<cleanup>()

Wrapper for
L<B<curl_multi_cleanup>|https://curl.haxx.se/libcurl/c/curl_multi_cleanup.html>.

=item method B<add-handle>(LibCurl::EasyHandle $handle)

Wrapper for
L<B<curl_multi_add_handle>|https://curl.haxx.se/libcurl/c/curl_multi_add_handle.html>.

=item method B<remove-handle>(LibCurl::EasyHandle $handle)

Wrapper for
L<B<curl_multi_remove_handle>|https://curl.haxx.se/libcurl/c/curl_multi_remove_handle.html>.

=item multi method B<setopt>($option, long $param)

Wrapper for
L<B<curl_multi_setopt>|https://curl.haxx.se/libcurl/c/curl_multi_setopt.html>.

=item method B<perform>(int32 $running-handles is rw)

Wrapper for
L<B<curl_multi_perform>|https://curl.haxx.se/libcurl/c/curl_multi_perform.html>.

If B<CURLM_CALL_MULTI_PERFORM> is returned, perform is immediately
called again.

=item method B<wait>(int32 $timeout-ms, int32 $numfds is rw)

Wrapper for
L<B<curl_multi_wait>|https://curl.haxx.se/libcurl/c/curl_multi_wait.html>.

=item method B<info>(int32 $msgs-in-queue is rw) returns LibCurl::CURLMsg

Wrapper for
L<B<curl_multi_info_read>|https://curl.haxx.se/libcurl/c/curl_multi_info_read.html>.

=end pod
