ShutdownLayer.cpp 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. *
  3. * This Source Code Form is subject to the terms of the Mozilla Public
  4. * License, v. 2.0. If a copy of the MPL was not distributed with this
  5. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  6. #include "mozilla/Assertions.h"
  7. #include "ShutdownLayer.h"
  8. #include "prerror.h"
  9. #include "private/pprio.h"
  10. #include "prmem.h"
  11. #include <winsock2.h>
  12. static PRDescIdentity sWinSockShutdownLayerIdentity;
  13. static PRIOMethods sWinSockShutdownLayerMethods;
  14. static PRIOMethods *sWinSockShutdownLayerMethodsPtr = nullptr;
  15. namespace mozilla {
  16. namespace net {
  17. extern PRDescIdentity nsNamedPipeLayerIdentity;
  18. } // namespace net
  19. } // namespace mozilla
  20. PRStatus
  21. WinSockClose(PRFileDesc *aFd)
  22. {
  23. MOZ_RELEASE_ASSERT(aFd->identity == sWinSockShutdownLayerIdentity,
  24. "Windows shutdown layer not on the top of the stack");
  25. PROsfd osfd = PR_FileDesc2NativeHandle(aFd);
  26. if (osfd != -1) {
  27. shutdown(osfd, SD_BOTH);
  28. }
  29. aFd->identity = PR_INVALID_IO_LAYER;
  30. if (aFd->lower) {
  31. return aFd->lower->methods->close(aFd->lower);
  32. } else {
  33. return PR_SUCCESS;
  34. }
  35. }
  36. nsresult mozilla::net::AttachShutdownLayer(PRFileDesc *aFd)
  37. {
  38. if (!sWinSockShutdownLayerMethodsPtr) {
  39. sWinSockShutdownLayerIdentity =
  40. PR_GetUniqueIdentity("windows shutdown call layer");
  41. sWinSockShutdownLayerMethods = *PR_GetDefaultIOMethods();
  42. sWinSockShutdownLayerMethods.close = WinSockClose;
  43. sWinSockShutdownLayerMethodsPtr = &sWinSockShutdownLayerMethods;
  44. }
  45. if (mozilla::net::nsNamedPipeLayerIdentity &&
  46. PR_GetIdentitiesLayer(aFd, mozilla::net::nsNamedPipeLayerIdentity)) {
  47. // Do not attach shutdown layer on named pipe layer,
  48. // it is for PR_NSPR_IO_LAYER only.
  49. return NS_OK;
  50. }
  51. PRFileDesc * layer;
  52. PRStatus status;
  53. layer = PR_CreateIOLayerStub(sWinSockShutdownLayerIdentity,
  54. sWinSockShutdownLayerMethodsPtr);
  55. if (!layer) {
  56. return NS_OK;
  57. }
  58. status = PR_PushIOLayer(aFd, PR_NSPR_IO_LAYER, layer);
  59. if (status == PR_FAILURE) {
  60. PR_DELETE(layer);
  61. return NS_ERROR_FAILURE;
  62. }
  63. return NS_OK;
  64. }